@propbinder/mobile-design 0.0.24 → 0.0.26

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.
@@ -1 +1 @@
1
- {"version":3,"file":"propbinder-mobile-design.mjs","sources":["../../../projects/mobile-design-lib/src/components/shared/mobile-page-base.ts","../../../projects/mobile-design-lib/src/components/shared/directives/long-press.directive.ts","../../../projects/mobile-design-lib/src/components/list-item/ds-mobile-list-item.ts","../../../projects/mobile-design-lib/src/components/action-list-item/ds-mobile-action-list-item.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts","../../../projects/mobile-design-lib/src/components/page-main/ds-mobile-page-main.ts","../../../projects/mobile-design-lib/src/components/page-details/ds-mobile-page-details.ts","../../../projects/mobile-design-lib/src/components/content/ds-mobile-content.ts","../../../projects/mobile-design-lib/src/components/header-content/ds-mobile-header-content.ts","../../../projects/mobile-design-lib/src/components/post-card/ds-mobile-post-card.ts","../../../projects/mobile-design-lib/src/components/comment/ds-mobile-comment.ts","../../../projects/mobile-design-lib/src/components/post-composer/ds-mobile-post-composer.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/index.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts","../../../projects/mobile-design-lib/src/components/contact-list-item/ds-mobile-contact-list-item.ts","../../../projects/mobile-design-lib/src/components/app-layout/ds-mobile-app-layout.ts","../../../projects/mobile-design-lib/src/components/tabs/ds-mobile-tabs.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-header.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-footer.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-image.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-pdf.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox.service.ts","../../../projects/mobile-design-lib/src/components/lightbox/index.ts","../../../projects/mobile-design-lib/src/components/inline-photo/ds-mobile-inline-photo.ts","../../../projects/mobile-design-lib/src/components/modal/ds-mobile-modal.service.ts","../../../projects/mobile-design-lib/src/components/modal/index.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/index.ts","../../../projects/mobile-design-lib/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts","../../../projects/mobile-design-lib/src/components/file-attachment/ds-mobile-file-attachment.ts","../../../projects/mobile-design-lib/src/components/swiper/ds-mobile-swiper.ts","../../../projects/mobile-design-lib/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts","../../../projects/mobile-design-lib/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts","../../../projects/mobile-design-lib/src/components/handbook-folder/ds-mobile-handbook-folder.ts","../../../projects/mobile-design-lib/src/components/index.ts","../../../projects/mobile-design-lib/src/services/user.service.ts","../../../projects/mobile-design-lib/src/pages/community.page.ts","../../../projects/mobile-design-lib/src/pages/handbook.page.ts","../../../projects/mobile-design-lib/src/pages/home.page.ts","../../../projects/mobile-design-lib/src/animations/page-transitions.ts","../../../projects/mobile-design-lib/src/components/tab-bar/ds-mobile-tab-bar.ts","../../../projects/mobile-design-lib/src/pages/inquiries.example.ts","../../../projects/mobile-design-lib/src/components/list-item-static/ds-mobile-list-item-static.ts","../../../projects/mobile-design-lib/src/pages/inquiry-detail.example.ts","../../../projects/mobile-design-lib/src/components/ds-mobile-tabs.ts","../../../projects/mobile-design-lib/src/pages/mobile-tabs-example.component.ts","../../../projects/mobile-design-lib/src/pages/post-create.page.ts","../../../projects/mobile-design-lib/src/pages/post-detail.page.ts","../../../projects/mobile-design-lib/src/services/whitelabel.service.ts","../../../projects/mobile-design-lib/src/components/logo/ds-logo.ts","../../../projects/mobile-design-lib/src/components/avatar-with-badge/ds-avatar-with-badge.ts","../../../projects/mobile-design-lib/src/pages/whitelabel-demo.page.ts","../../../projects/mobile-design-lib/src/public-api.ts","../../../projects/mobile-design-lib/src/propbinder-mobile-design.ts"],"sourcesContent":["import { input, computed, Directive } from '@angular/core';\r\n\r\n/**\r\n * Content width preset values\r\n * - 'narrow' - 640px max width (reading content)\r\n * - 'standard' - 1024px max width (default)\r\n * - 'wide' - 1440px max width (dashboards)\r\n * - 'full' - 100% width (no max)\r\n */\r\nexport type ContentWidth = 'narrow' | 'standard' | 'wide' | 'full';\r\n\r\n/**\r\n * MobilePageBase\r\n * \r\n * Shared base class for mobile page components (ds-mobile-page-main, ds-mobile-page-details).\r\n * Provides consistent content width control across all page types.\r\n * \r\n * **Padding Strategy:**\r\n * - All pages use 20px horizontal padding globally\r\n * - For tappable lists, use negative margins (e.g., margin: 0 -8px) to create full-width sections\r\n * - This approach simplifies padding management and provides consistency\r\n * \r\n * @internal This is a base class and should not be used directly.\r\n */\r\n@Directive()\r\nexport abstract class MobilePageBase {\r\n /**\r\n * Maximum content width (desktop only)\r\n * \r\n * **Options:**\r\n * - `'narrow'` (640px) - For reading content, forms\r\n * - `'standard'` (1024px) - Default for most pages\r\n * - `'wide'` (1440px) - For dashboards, tables\r\n * - `'full'` - No max-width constraint\r\n * \r\n * **Note:** Only applies on desktop (>= 768px). Mobile is always full width.\r\n * \r\n * @default 'standard'\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Narrow reading layout -->\r\n * <ds-mobile-page-main title=\"Article\" contentWidth=\"narrow\">\r\n * \r\n * <!-- Wide dashboard -->\r\n * <ds-mobile-page-main title=\"Dashboard\" contentWidth=\"wide\">\r\n * ```\r\n */\r\n contentWidth = input<ContentWidth>('standard');\r\n\r\n /**\r\n * Resolved max-width value (computed)\r\n * Maps preset values to pixel values\r\n * \r\n * @internal\r\n */\r\n protected maxWidthValue = computed(() => {\r\n const w = this.contentWidth();\r\n \r\n const widthMap: Record<ContentWidth, string> = {\r\n 'narrow': '640px',\r\n 'standard': '1024px',\r\n 'wide': '1440px',\r\n 'full': '100%'\r\n };\r\n \r\n return widthMap[w];\r\n });\r\n}\r\n\r\n","import { \r\n Directive, \r\n Output, \r\n EventEmitter, \r\n HostListener, \r\n Input,\r\n OnDestroy \r\n} from '@angular/core';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileLongPressDirective\r\n * \r\n * A reusable directive for handling long press interactions on mobile devices.\r\n * Provides haptic feedback and prevents long press when touching interactive elements.\r\n * \r\n * Features:\r\n * - Configurable duration and movement threshold\r\n * - Automatic haptic feedback (with fallback to navigator.vibrate)\r\n * - Excludes interactive elements (buttons, links, inputs)\r\n * - Handles touchmove cancellation\r\n * - Context menu support (right-click on desktop)\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <div dsMobileLongPress (longPress)=\"handleLongPress()\">\r\n * Long press me\r\n * </div>\r\n * \r\n * <!-- Custom duration and threshold -->\r\n * <div \r\n * dsMobileLongPress \r\n * [longPressDuration]=\"800\"\r\n * [moveThreshold]=\"15\"\r\n * [excludeSelectors]=\"'button, a, .no-longpress'\"\r\n * (longPress)=\"showContextMenu()\">\r\n * Custom long press\r\n * </div>\r\n * ```\r\n */\r\n@Directive({\r\n selector: '[dsMobileLongPress]',\r\n standalone: true\r\n})\r\nexport class DsMobileLongPressDirective implements OnDestroy {\r\n /**\r\n * Duration in milliseconds to trigger long press\r\n * @default 500\r\n */\r\n @Input() longPressDuration = 500;\r\n\r\n /**\r\n * Maximum movement in pixels before canceling long press\r\n * @default 10\r\n */\r\n @Input() moveThreshold = 10;\r\n\r\n /**\r\n * CSS selectors to exclude from long press detection\r\n * @default 'button, a, input, select, textarea, [role=\"button\"]'\r\n */\r\n @Input() excludeSelectors = 'button, a, input, select, textarea, [role=\"button\"]';\r\n\r\n /**\r\n * Haptic feedback style (Light, Medium, Heavy)\r\n * @default ImpactStyle.Medium\r\n */\r\n @Input() hapticStyle: ImpactStyle = ImpactStyle.Medium;\r\n\r\n /**\r\n * Enable/disable haptic feedback\r\n * @default true\r\n */\r\n @Input() enableHaptics = true;\r\n\r\n /**\r\n * Emits when long press is triggered\r\n */\r\n @Output() longPress = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press starts (timer begins)\r\n */\r\n @Output() longPressStart = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press is cancelled\r\n */\r\n @Output() longPressCancel = new EventEmitter<void>();\r\n\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n\r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n handleTouchStart(event: TouchEvent): void {\r\n // Don't start long press if touching interactive elements\r\n const target = event.target as HTMLElement;\r\n if (target.closest(this.excludeSelectors)) {\r\n return;\r\n }\r\n\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n\r\n // Emit start event\r\n this.longPressStart.emit();\r\n\r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n\r\n // Haptic feedback for long press\r\n if (this.enableHaptics) {\r\n await this.triggerHaptics();\r\n }\r\n }, this.longPressDuration);\r\n }\r\n\r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n @HostListener('touchend', ['$event'])\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n \r\n if (!this.longPressTriggered) {\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n\r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n @HostListener('touchmove', ['$event'])\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n\r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n\r\n // Cancel long press if moved too far\r\n if (deltaX > this.moveThreshold || deltaY > this.moveThreshold) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n @HostListener('contextmenu', ['$event'])\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n\r\n /**\r\n * Trigger haptic feedback\r\n */\r\n private async triggerHaptics(): Promise<void> {\r\n try {\r\n await Haptics.impact({ style: this.hapticStyle });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n // Map haptic styles to vibration durations\r\n const vibrationMap = {\r\n [ImpactStyle.Light]: 30,\r\n [ImpactStyle.Medium]: 50,\r\n [ImpactStyle.Heavy]: 80\r\n };\r\n navigator.vibrate(vibrationMap[this.hapticStyle] || 50);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup on destroy\r\n */\r\n ngOnDestroy(): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n }\r\n}\r\n\r\n","import { Component, input, output, computed, signal, PLATFORM_ID, inject } from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { DsMobileLongPressDirective } from '../shared/directives/long-press.directive';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileListItemComponent\r\n * \r\n * A versatile, reusable list item component for mobile applications.\r\n * Supports both interactive and non-interactive modes with flexible content projection.\r\n * \r\n * Features:\r\n * - Interactive mode with click and long-press support\r\n * - Pseudo-element background extends 8px beyond bounds (no negative margins needed)\r\n * - Flexible content slots (leading, main, trailing)\r\n * - Optional structured inputs for common use cases (title, subtitle)\r\n * - Accessibility features (focus states, ARIA attributes)\r\n * - Disabled and loading states\r\n * \r\n * This component serves as the foundation for specialized list item types like posts,\r\n * notifications, messages, contacts, and other list content.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple structured usage -->\r\n * <ds-mobile-list-item\r\n * title=\"Document Title\"\r\n * subtitle=\"Supporting text\"\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\">\r\n * \r\n * <ds-icon content-leading name=\"document\" />\r\n * </ds-mobile-list-item>\r\n * \r\n * <!-- Flexible custom usage -->\r\n * <ds-mobile-list-item\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\"\r\n * (longPress)=\"showContextMenu()\">\r\n * \r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n * \r\n * <div content-main>\r\n * <h3>Custom Content</h3>\r\n * <p>Full control over layout and styling</p>\r\n * </div>\r\n * \r\n * <button content-trailing (click)=\"handleAction($event)\">\r\n * Action\r\n * </button>\r\n * </ds-mobile-list-item>\r\n * \r\n * <!-- Non-interactive read-only -->\r\n * <ds-mobile-list-item\r\n * title=\"Read-only Item\"\r\n * subtitle=\"No interaction\">\r\n * <ds-icon content-leading name=\"info\" />\r\n * </ds-mobile-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n hostDirectives: [\r\n {\r\n directive: DsMobileLongPressDirective,\r\n outputs: ['longPress']\r\n }\r\n ],\r\n host: {\r\n '[class.interactive]': 'interactive() && !disabled()',\r\n '[class.disabled]': 'disabled()',\r\n '[class.loading]': 'loading()',\r\n '[class.no-divider]': '!showDivider()',\r\n '[class.variant-feed]': 'variant() === \"feed\"',\r\n '[class.variant-detail]': 'variant() === \"detail\"',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '[attr.role]': 'interactive() ? \"button\" : null',\r\n '[attr.tabindex]': 'interactive() && !disabled() ? \"0\" : null',\r\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\r\n '[style.--leading-size]': 'leadingSize()',\r\n '[style.--interactive-offset]': 'interactiveOffset()',\r\n '[style.--divider-spacing]': 'dividerSpacing()',\r\n '(click)': 'handleClick($event)',\r\n '(keydown.enter)': 'handleKeyDown($event)',\r\n '(keydown.space)': 'handleKeyDown($event)',\r\n '(longPress)': 'handleLongPress()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: relative;\r\n padding: var(--item-padding-top, 12px) 0 var(--item-padding-bottom, 12px) 0;\r\n box-sizing: border-box;\r\n /* CSS variables defined at host level for use by children and pseudo-elements */\r\n --leading-size: 32px;\r\n --content-gap: 12px;\r\n --interactive-offset: 8px;\r\n }\r\n \r\n /* Divider line on host */\r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: calc(var(--leading-size) + var(--content-gap));\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default, #e5e5e5);\r\n z-index: 1;\r\n display: var(--divider-display, block);\r\n }\r\n \r\n .list-item-inner {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n gap: var(--content-gap);\r\n position: relative;\r\n }\r\n \r\n /* Pseudo-element for interactive background */\r\n :host(.interactive) .list-item-inner::before {\r\n content: '';\r\n position: absolute;\r\n top: calc(-1 * var(--interactive-offset));\r\n left: calc(-1 * var(--interactive-offset));\r\n right: calc(-1 * var(--interactive-offset));\r\n bottom: calc(-1 * var(--interactive-offset));\r\n background: var(--color-background-primary, #ffffff);\r\n border-radius: 16px;\r\n z-index: -1;\r\n pointer-events: none;\r\n }\r\n \r\n /* Interactive states */\r\n :host(.interactive) {\r\n cursor: pointer;\r\n }\r\n \r\n /* Hover state (desktop only) */\r\n @media (hover: hover) and (pointer: fine) {\r\n :host(.interactive):hover .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n }\r\n \r\n /* Active state */\r\n :host(.interactive):active .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n /* Focus visible for keyboard navigation */\r\n :host(.interactive):focus-visible {\r\n outline: none;\r\n }\r\n \r\n :host(.interactive):focus-visible .list-item-inner::before {\r\n outline: 2px solid var(--color-brand-primary, #5d5fef);\r\n outline-offset: 2px;\r\n }\r\n \r\n /* Disabled state */\r\n :host(.disabled) {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n }\r\n \r\n /* Loading state */\r\n :host(.loading) {\r\n pointer-events: none;\r\n }\r\n \r\n /* Variants */\r\n :host(.variant-detail) .list-item-inner {\r\n padding: 0;\r\n }\r\n \r\n :host(.variant-compact) .list-item-inner {\r\n gap: 8px;\r\n }\r\n \r\n /* Content slots */\r\n .content-leading {\r\n flex-shrink: 0;\r\n width: var(--leading-size);\r\n height: var(--leading-size);\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-start;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n /* Structured content styles */\r\n .structured-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .structured-subtitle {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n `],\r\n template: `\r\n <div class=\"list-item-inner\">\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n \r\n <div class=\"content-main\">\r\n @if (title()) {\r\n <h3 class=\"structured-title\">{{ title() }}</h3>\r\n }\r\n @if (subtitle()) {\r\n <p class=\"structured-subtitle\">{{ subtitle() }}</p>\r\n }\r\n \r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n \r\n <div class=\"content-trailing\">\r\n @if (interactive() && enableLongPress() && showDesktopMoreButton() && isDesktop()) {\r\n <ds-icon-button\r\n class=\"desktop-more-button\"\r\n icon=\"remixMoreFill\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleMoreButtonClick($event)\"\r\n aria-label=\"More options\">\r\n </ds-icon-button>\r\n }\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileListItemComponent {\r\n private platformId = inject(PLATFORM_ID);\r\n \r\n /**\r\n * Detect if viewport is desktop size\r\n * Use viewport width for breakpoint detection (show button on tablet and above)\r\n */\r\n isDesktop = signal<boolean>(false);\r\n \r\n constructor() {\r\n if (isPlatformBrowser(this.platformId)) {\r\n // Show button on tablet breakpoint and above (768px+)\r\n const isDesktopViewport = window.innerWidth >= 768;\r\n \r\n console.log('[ListItem] Desktop detection:', {\r\n innerWidth: window.innerWidth,\r\n isDesktopViewport\r\n });\r\n \r\n this.isDesktop.set(isDesktopViewport);\r\n \r\n // Listen for window resize to update detection\r\n window.addEventListener('resize', () => {\r\n const newIsDesktop = window.innerWidth >= 768;\r\n if (newIsDesktop !== this.isDesktop()) {\r\n console.log('[ListItem] Viewport changed, updating desktop detection:', newIsDesktop);\r\n this.isDesktop.set(newIsDesktop);\r\n }\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * CSS size value for the leading content area (e.g., '32px', '40px', '48px')\r\n * Defaults to '32px' for standard list item avatars/icons\r\n */\r\n leadingSize = input<string>('32px');\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related items\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the list item is interactive (clickable and long-pressable)\r\n * When true, adds interactive background, cursor pointer, and touch handlers\r\n */\r\n interactive = input<boolean>(false);\r\n \r\n /**\r\n * Whether the list item is disabled\r\n * Disables all interactions and reduces opacity\r\n */\r\n disabled = input<boolean>(false);\r\n \r\n /**\r\n * Whether the list item is in a loading state\r\n * Disables interactions but maintains full opacity\r\n */\r\n loading = input<boolean>(false);\r\n \r\n /**\r\n * Enable long-press interaction when interactive is true\r\n * Set to false to disable long-press but keep click\r\n */\r\n enableLongPress = input<boolean>(true);\r\n \r\n /**\r\n * Show \"more actions\" button on desktop for items with long-press enabled\r\n * Only visible on desktop (hover: hover) and when enableLongPress is true\r\n * Clicking this button triggers the same handler as long-press on mobile\r\n * @default true\r\n */\r\n showDesktopMoreButton = input<boolean>(true);\r\n \r\n /**\r\n * Offset distance for the interactive background pseudo-element\r\n * Extends the background beyond the content bounds\r\n * @default '8px'\r\n */\r\n interactiveOffset = input<string>('8px');\r\n \r\n /**\r\n * Optional structured title text\r\n * Provides a simple way to add title without custom markup\r\n */\r\n title = input<string>();\r\n \r\n /**\r\n * Optional structured subtitle text\r\n * Provides a simple way to add subtitle without custom markup\r\n */\r\n subtitle = input<string>();\r\n \r\n /**\r\n * Whether to show the divider line below the list item\r\n * Automatically hidden on last-child and detail variant\r\n * @default true\r\n */\r\n showDivider = input<boolean>(true);\r\n \r\n /**\r\n * Spacing around the divider (top and bottom padding)\r\n * @default '4px'\r\n */\r\n dividerSpacing = input<string>('4px');\r\n \r\n /**\r\n * Emits when the list item is clicked (if interactive and not disabled)\r\n */\r\n itemClick = output<void>();\r\n \r\n /**\r\n * Emits when the desktop more actions button is clicked\r\n * This is separate from longPress to give more control to parent components\r\n * Typically, you can use (longPress) for both mobile and desktop actions\r\n */\r\n moreButtonClick = output<Event>();\r\n \r\n /**\r\n * Track if long press was triggered to prevent click\r\n */\r\n private longPressTriggered = false;\r\n \r\n /**\r\n * Check if leading content slot has content\r\n * Always true to maintain consistent layout\r\n */\r\n hasLeadingContent = computed(() => true);\r\n \r\n /**\r\n * Check if trailing content slot has content\r\n * Always true to maintain consistent layout\r\n */\r\n hasTrailingContent = computed(() => true);\r\n \r\n /**\r\n * Handle click events\r\n */\r\n handleClick(event: Event): void {\r\n console.log('[ListItem] Click event fired', {\r\n interactive: this.interactive(),\r\n disabled: this.disabled(),\r\n loading: this.loading(),\r\n longPressTriggered: this.longPressTriggered,\r\n target: event.target\r\n });\r\n \r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n console.log('[ListItem] Click ignored - not interactive or disabled/loading');\r\n return;\r\n }\r\n \r\n // Don't emit click if it came from an interactive child element\r\n // (but not the host element itself)\r\n const target = event.target as HTMLElement;\r\n const closestInteractive = target.closest('button, a, input, select, textarea, [role=\"button\"]');\r\n \r\n // Check if the interactive element is a child, not the host itself\r\n if (closestInteractive && closestInteractive !== event.currentTarget) {\r\n console.log('[ListItem] Click ignored - came from interactive child:', closestInteractive);\r\n return;\r\n }\r\n \r\n if (!this.longPressTriggered) {\r\n console.log('[ListItem] Emitting itemClick');\r\n this.itemClick.emit();\r\n } else {\r\n console.log('[ListItem] Click ignored - long press was triggered');\r\n }\r\n \r\n this.longPressTriggered = false;\r\n }\r\n \r\n /**\r\n * Handle keyboard events (Enter/Space)\r\n */\r\n handleKeyDown(event: KeyboardEvent): void {\r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n return;\r\n }\r\n \r\n event.preventDefault();\r\n this.itemClick.emit();\r\n }\r\n \r\n /**\r\n * Handle long press events from the directive\r\n * Set the flag to prevent the subsequent click event\r\n */\r\n handleLongPress(): void {\r\n this.longPressTriggered = true;\r\n // Reset the flag after a short delay to allow for the next interaction\r\n setTimeout(() => {\r\n this.longPressTriggered = false;\r\n }, 100);\r\n }\r\n \r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation to prevent triggering itemClick\r\n * Emits moreButtonClick for parent components to handle\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n console.log('[ListItem] Desktop more button clicked');\r\n \r\n // Stop propagation to prevent triggering itemClick\r\n event.stopPropagation();\r\n event.preventDefault();\r\n \r\n // Emit the more button click event\r\n this.moreButtonClick.emit(event);\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { DsMobileListItemComponent } from '../list-item/ds-mobile-list-item';\r\n\r\n/**\r\n * DsMobileActionListItemComponent\r\n * \r\n * Specialized list item for action sheets and menus.\r\n * Wraps ds-mobile-list-item with action-specific styling:\r\n * - Vertically centered content\r\n * - Interactive by default\r\n * - No dividers (controlled per-item)\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-action-list-item\r\n * title=\"Edit\"\r\n * [showDivider]=\"true\"\r\n * (itemClick)=\"handleEdit()\">\r\n * <ds-icon content-leading name=\"remixEditLine\" size=\"20px\" />\r\n * </ds-mobile-action-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-action-list-item',\r\n standalone: true,\r\n imports: [DsMobileListItemComponent],\r\n template: `\r\n <ds-mobile-list-item\r\n [title]=\"title()\"\r\n [interactive]=\"true\"\r\n [enableLongPress]=\"false\"\r\n [showDivider]=\"showDivider()\"\r\n [disabled]=\"disabled()\"\r\n (itemClick)=\"itemClick.emit()\">\r\n \r\n <div content-leading>\r\n <ng-content select=\"[action-icon]\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `,\r\n styles: [`\r\n /* Center all content vertically for action items */\r\n :host ::ng-deep ds-mobile-list-item .list-item-inner {\r\n align-items: center;\r\n }\r\n \r\n /* Center icon within leading slot */\r\n :host ::ng-deep ds-mobile-list-item .content-leading {\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n /* Remove gap from content-main for single-line actions */\r\n :host ::ng-deep ds-mobile-list-item .content-main {\r\n gap: 0;\r\n justify-content: center;\r\n }\r\n `]\r\n})\r\nexport class DsMobileActionListItemComponent {\r\n /**\r\n * Action title text\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Whether to show divider below item\r\n * @default false\r\n */\r\n showDivider = input<boolean>(false);\r\n \r\n /**\r\n * Whether the action is disabled\r\n * @default false\r\n */\r\n disabled = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the action item is clicked\r\n */\r\n itemClick = output<void>();\r\n}\r\n\r\n","import { Component, Input, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileActionListItemComponent } from '../action-list-item/ds-mobile-action-list-item';\r\n\r\nexport interface ActionResult {\r\n action: string;\r\n}\r\n\r\nexport interface ActionItem {\r\n action: string;\r\n title: string;\r\n icon: string;\r\n destructive?: boolean;\r\n}\r\n\r\nexport interface ActionGroup {\r\n actions: ActionItem[];\r\n}\r\n\r\n/**\r\n * DsMobileActionsBottomSheetComponent\r\n * \r\n * Generic bottom sheet for displaying action lists.\r\n * Supports custom action groups or preset content actions (posts/comments).\r\n * Action groups are automatically separated by full-width dividers.\r\n * \r\n * @example Custom actions with auto-height (recommended to avoid cropping)\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * customActionGroups: [\r\n * {\r\n * actions: [\r\n * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },\r\n * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }\r\n * ]\r\n * },\r\n * {\r\n * actions: [\r\n * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }\r\n * ]\r\n * }\r\n * ]\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n * \r\n * const result = await sheet.onWillDismiss();\r\n * if (result.data?.action) {\r\n * // Handle the action\r\n * }\r\n * ```\r\n * \r\n * @example Preset content actions\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * isOwnContent: false\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-actions-bottom-sheet',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsMobileActionListItemComponent],\r\n template: `\r\n <div class=\"actions-sheet\">\r\n <!-- Actions List -->\r\n <div class=\"actions-list\">\r\n @for (group of actionGroups(); track $index; let isLast = $last) {\r\n <!-- Action Group -->\r\n <div class=\"action-group\">\r\n @for (actionItem of group.actions; track actionItem.action; let isLastInGroup = $last) {\r\n <ds-mobile-action-list-item\r\n [title]=\"actionItem.title\"\r\n [showDivider]=\"!isLastInGroup\"\r\n [class.destructive]=\"actionItem.destructive\"\r\n (itemClick)=\"selectAction(actionItem.action)\">\r\n <ds-icon \r\n action-icon \r\n [name]=\"actionItem.icon\" \r\n size=\"20px\" \r\n [class.destructive-icon]=\"actionItem.destructive\" />\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n \r\n <!-- Full-width divider between groups -->\r\n @if (!isLast) {\r\n <div class=\"action-group-divider\"></div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n .actions-sheet {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n padding-bottom: env(safe-area-inset-bottom, 0px);\r\n }\r\n \r\n /* Actions List */\r\n .actions-list {\r\n display: flex;\r\n flex-direction: column;\r\n padding-top: 16px; /* Only top padding for the container */\r\n }\r\n \r\n /* Action Group - padding on groups instead of list */\r\n .action-group {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 0 16px; /* Horizontal padding on each group */\r\n }\r\n \r\n /* Override default background color to transparent so hover state is visible */\r\n /* Need ::ng-deep because ds-mobile-list-item uses :host styles internally */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item {\r\n --color-background-primary: transparent;\r\n --color-background-neutral-primary-hover: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n /* Ensure the interactive background is visible */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .list-item-inner::before {\r\n z-index: 0 !important;\r\n }\r\n \r\n /* Ensure content is above the background */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-leading,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-main,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-trailing {\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n /* Hide divider on last list item using CSS variable */\r\n ds-mobile-action-list-item:last-of-type {\r\n --divider-display: none;\r\n }\r\n \r\n /* Destructive action styling */\r\n ds-mobile-action-list-item.destructive {\r\n --text-color-default-primary: var(--color-error-base, #ef4444);\r\n }\r\n \r\n .destructive-icon {\r\n color: var(--color-error-base, #ef4444);\r\n }\r\n \r\n /* Full-width divider between action groups */\r\n .action-group-divider {\r\n height: 1px;\r\n background: var(--color-border-subtle, #e5e5e5);\r\n margin: 8px 0;\r\n }\r\n `]\r\n})\r\nexport class DsMobileActionsBottomSheetComponent {\r\n /**\r\n * Custom action groups to display (overrides isOwnContent)\r\n */\r\n @Input() customActionGroups?: ActionGroup[];\r\n \r\n /**\r\n * Whether this content belongs to the current user (for preset content actions)\r\n */\r\n @Input() isOwnContent: boolean = false;\r\n \r\n /**\r\n * Computed action groups - uses custom groups if provided, otherwise falls back to preset content actions\r\n */\r\n actionGroups = computed<ActionGroup[]>(() => {\r\n // Use custom action groups if provided\r\n if (this.customActionGroups) {\r\n return this.customActionGroups;\r\n }\r\n \r\n // Otherwise fall back to preset content actions\r\n if (this.isOwnContent) {\r\n // Own content: Group 1 (Edit, Delete) + Group 2 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'edit',\r\n title: 'Rediger',\r\n icon: 'remixEditLine',\r\n destructive: false\r\n },\r\n {\r\n action: 'delete',\r\n title: 'Slet',\r\n icon: 'remixDeleteBinLine',\r\n destructive: true\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false\r\n }\r\n ]\r\n }\r\n ];\r\n } else {\r\n // Other users' content: Group 1 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false\r\n }\r\n ]\r\n }\r\n ];\r\n }\r\n });\r\n \r\n constructor(private modalController: ModalController) {}\r\n \r\n /**\r\n * Handle action selection and dismiss with result\r\n */\r\n selectAction(action: string): void {\r\n this.modalController.dismiss(\r\n { action } as ActionResult,\r\n 'select'\r\n );\r\n }\r\n}\r\n\r\n// Legacy exports for backwards compatibility\r\nexport { DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent };\r\nexport { DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent };\r\nexport type { ActionResult as PostActionResult };\r\nexport type { ActionResult as CommentActionResult };\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { ComponentRef } from '@angular/core';\r\n\r\n/**\r\n * Configuration options for the bottom sheet modal\r\n */\r\nexport interface BottomSheetOptions {\r\n /** The component to display in the bottom sheet */\r\n component: any;\r\n /** Component props to pass to the modal content */\r\n componentProps?: { [key: string]: any };\r\n /** Breakpoints for the bottom sheet (0-1 values representing percentage of screen) */\r\n breakpoints?: number[];\r\n /** Initial breakpoint to open the sheet at */\r\n initialBreakpoint?: number;\r\n /** Show/hide the drag handle */\r\n handle?: boolean;\r\n /** Custom CSS class for styling */\r\n cssClass?: string | string[];\r\n /** Whether backdrop dismisses the modal */\r\n backdropDismiss?: boolean;\r\n /** Backdrop opacity (0-1) */\r\n backdropOpacity?: number;\r\n /** Enable backdrop blur effect */\r\n backdropBlur?: boolean;\r\n /** Keyboard close behavior */\r\n keyboardClose?: boolean;\r\n /** Auto-height mode: sheet sizes to content instead of using fixed breakpoints */\r\n autoHeight?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileBottomSheetService\r\n * \r\n * Service for creating and managing Ionic 6 bottom sheet modals.\r\n * Based on the Ionic blog article: https://ionic.io/blog/5-examples-of-the-new-ionic-6-bottom-sheet-modal\r\n * \r\n * Features:\r\n * - Multiple breakpoints for snap-to positions\r\n * - Customizable initial height\r\n * - Optional drag handle\r\n * - Backdrop blur effect\r\n * - Custom styling support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private bottomSheet: DsMobileBottomSheetService) {}\r\n * \r\n * async openSheet() {\r\n * const sheet = await this.bottomSheet.create({\r\n * component: PostCreateComponent,\r\n * breakpoints: [0, 0.5, 0.9],\r\n * initialBreakpoint: 0.5,\r\n * handle: true\r\n * });\r\n * \r\n * const result = await sheet.onWillDismiss();\r\n * console.log('Sheet dismissed with:', result.data);\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileBottomSheetService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Create and present a bottom sheet modal\r\n * \r\n * @param options Configuration options for the bottom sheet\r\n * @returns Promise that resolves to the modal instance\r\n */\r\n async create(options: BottomSheetOptions): Promise<HTMLIonModalElement> {\r\n const {\r\n component,\r\n componentProps = {},\r\n breakpoints = [0, 0.5, 0.9],\r\n initialBreakpoint = 0.5,\r\n handle = true,\r\n cssClass = '',\r\n backdropDismiss = true,\r\n backdropOpacity,\r\n backdropBlur = false,\r\n keyboardClose = true,\r\n autoHeight = false\r\n } = options;\r\n\r\n // Build CSS classes array\r\n const cssClasses = ['ds-bottom-sheet'];\r\n if (backdropBlur) {\r\n cssClasses.push('ds-bottom-sheet--blur');\r\n }\r\n if (autoHeight) {\r\n cssClasses.push('auto-height');\r\n }\r\n if (typeof cssClass === 'string' && cssClass) {\r\n cssClasses.push(cssClass);\r\n } else if (Array.isArray(cssClass)) {\r\n cssClasses.push(...cssClass);\r\n }\r\n\r\n const modal = await this.modalController.create({\r\n component,\r\n componentProps,\r\n breakpoints: autoHeight ? undefined : breakpoints,\r\n initialBreakpoint: autoHeight ? undefined : initialBreakpoint,\r\n handle: autoHeight ? false : handle,\r\n cssClass: cssClasses,\r\n backdropDismiss,\r\n keyboardClose,\r\n showBackdrop: true,\r\n canDismiss: backdropDismiss,\r\n // Remove animation delay for instant appearance\r\n animated: true,\r\n enterAnimation: undefined, // Use default but we'll customize via CSS\r\n leaveAnimation: undefined,\r\n ...(backdropOpacity !== undefined && { \r\n cssClass: [...cssClasses, 'ds-bottom-sheet--custom-backdrop']\r\n })\r\n });\r\n\r\n // Apply custom backdrop opacity if specified\r\n if (backdropOpacity !== undefined) {\r\n modal.style.setProperty('--backdrop-opacity', backdropOpacity.toString());\r\n }\r\n\r\n // Add ESC key listener to dismiss the modal\r\n const escKeyHandler = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n modal.dismiss(undefined, 'escape');\r\n }\r\n };\r\n \r\n // Add listener when modal is presented\r\n modal.addEventListener('ionModalDidPresent', () => {\r\n document.addEventListener('keydown', escKeyHandler);\r\n });\r\n \r\n // Remove listener when modal is dismissed\r\n modal.addEventListener('ionModalDidDismiss', () => {\r\n document.removeEventListener('keydown', escKeyHandler);\r\n });\r\n\r\n await modal.present();\r\n \r\n // Don't wait - return immediately so component can try to focus\r\n // while still in user gesture context\r\n return modal;\r\n }\r\n\r\n /**\r\n * Dismiss all open modals\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal overlay\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","import { Component, signal, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController, IonHeader, IonToolbar, IonTitle, IonContent, IonButtons } from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { Camera, CameraResultType, CameraSource } from '@capacitor/camera';\r\nimport { StatusBar } from '@capacitor/status-bar';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobilePostCreateBottomSheetComponent\r\n * \r\n * Bottom sheet modal for creating new posts in the community feed.\r\n * This is the modal content that gets displayed in the bottom sheet.\r\n * Features Threads-inspired interface with rich text editing capabilities.\r\n * \r\n * Auto-focuses the textarea and brings up the keyboard when opened.\r\n * \r\n * Usage: Use with DsMobileBottomSheetService to present as a bottom sheet\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-create-bottom-sheet',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonButtons,\r\n DsButtonComponent,\r\n DsIconButtonComponent\r\n ],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n }\r\n\r\n /* ============================================\r\n HEADER\r\n ============================================ */\r\n \r\n ion-header {\r\n box-shadow: none;\r\n }\r\n\r\n ion-toolbar {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --border-width: 0 0 1px 0;\r\n --border-color: var(--border-color-default);\r\n --padding-top: 12px;\r\n --padding-bottom: 8px;\r\n --min-height: 56px;\r\n }\r\n\r\n ion-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 22px;\r\n letter-spacing: -0.4px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n\r\n ion-button {\r\n --color: var(--color-text-secondary, #737373);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n }\r\n\r\n /* Make Post button pill-shaped */\r\n ion-buttons[slot=\"end\"] ds-button {\r\n --border-radius: 100px;\r\n }\r\n \r\n ion-buttons[slot=\"end\"] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n \r\n /* Make Cancel button pill-shaped */\r\n ion-buttons[slot=\"start\"] ds-button {\r\n --border-radius: 100px;\r\n }\r\n \r\n ion-buttons[slot=\"start\"] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n\r\n /* ============================================\r\n CONTENT AREA\r\n ============================================ */\r\n \r\n ion-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n }\r\n\r\n .post-create-container {\r\n padding: 24px 16px 16px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n \r\n .post-composer {\r\n display: flex;\r\n gap: 12px;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-composer__main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .post-composer__header {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 32px;\r\n }\r\n \r\n .post-composer__username {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .post-composer__textarea {\r\n width: 100%;\r\n min-height: 60px;\r\n max-height: 400px;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n background: transparent;\r\n padding: 0;\r\n cursor: text;\r\n overflow-y: auto;\r\n /* Auto-resize as user types */\r\n field-sizing: content;\r\n }\r\n \r\n .post-composer__textarea::placeholder {\r\n color: var(--color-text-tertiary, #999999);\r\n }\r\n \r\n /* Visual focus indicator - helps users see the textarea is ready */\r\n .post-composer__textarea:focus {\r\n outline: none;\r\n }\r\n \r\n /* Subtle animation to draw attention when empty */\r\n @keyframes gentlePulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.6; }\r\n }\r\n \r\n .post-composer__textarea:not(:focus):empty + .focus-hint {\r\n animation: gentlePulse 2s ease-in-out 1;\r\n }\r\n \r\n .post-composer__actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding-top: 12px;\r\n }\r\n \r\n .post-composer__actions ds-icon-button::ng-deep button {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n }\r\n \r\n /* ============================================\r\n IMAGE PREVIEW\r\n ============================================ */\r\n \r\n .image-previews {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n margin-top: 12px;\r\n }\r\n \r\n .image-preview {\r\n position: relative;\r\n width: 96px;\r\n height: 96px;\r\n border-radius: 12px;\r\n overflow: visible;\r\n }\r\n \r\n .preview-image {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n border-radius: 12px;\r\n border: 1px solid var(--border-color-default);\r\n object-fit: cover;\r\n }\r\n \r\n .remove-image-btn {\r\n position: absolute;\r\n top: -8px;\r\n right: -8px;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 50%;\r\n background: rgba(0, 0, 0, 0.6);\r\n backdrop-filter: blur(8px);\r\n border: 2px solid white;\r\n color: white;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n padding: 0;\r\n }\r\n \r\n .remove-image-btn:hover {\r\n background: rgba(0, 0, 0, 0.8);\r\n transform: scale(1.05);\r\n }\r\n \r\n .remove-image-btn:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n /* ============================================\r\n MOBILE OPTIMIZATIONS\r\n ============================================ */\r\n \r\n @media (max-width: 768px) {\r\n .post-create-container {\r\n padding: 12px 16px 24px;\r\n }\r\n\r\n .post-composer__textarea {\r\n min-height: 60px;\r\n max-height: 300px;\r\n /* Make tap target larger on mobile */\r\n padding: 8px;\r\n margin: -8px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <!-- Header with cancel and post buttons -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <ion-buttons slot=\"start\">\r\n <ds-button\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleCancel()\">\r\n Annuller\r\n </ds-button>\r\n </ion-buttons>\r\n <ion-title>{{ modalTitle() }}</ion-title>\r\n <ion-buttons slot=\"end\">\r\n <ds-button\r\n variant=\"primary\"\r\n size=\"sm\"\r\n [disabled]=\"!canPost()\"\r\n (clicked)=\"handlePost()\">\r\n {{ submitButtonLabel() }}\r\n </ds-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content -->\r\n <ion-content>\r\n <div class=\"post-create-container\">\r\n <div class=\"post-composer\">\r\n <div class=\"post-composer__main\">\r\n <textarea\r\n #textareaInput\r\n class=\"post-composer__textarea\"\r\n [(ngModel)]=\"postContent\"\r\n [placeholder]=\"placeholder()\"\r\n [readonly]=\"isReadonly\"\r\n (input)=\"handleInput()\"\r\n (focus)=\"handleFocus()\"\r\n inputmode=\"text\"\r\n enterkeyhint=\"done\"\r\n rows=\"1\">\r\n </textarea>\r\n \r\n <!-- Image Previews -->\r\n @if (selectedImages().length > 0) {\r\n <div class=\"image-previews\">\r\n @for (image of selectedImages(); track image; let i = $index) {\r\n <div class=\"image-preview\">\r\n <img [src]=\"image\" alt=\"Selected image\" class=\"preview-image\" />\r\n <button \r\n class=\"remove-image-btn\" \r\n (click)=\"handleRemoveImage(i)\"\r\n type=\"button\"\r\n aria-label=\"Fjern billede\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M12 4L4 12M4 4L12 12\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n <div class=\"post-composer__actions\">\r\n <ds-icon-button\r\n icon=\"remixImageLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddImage()\"\r\n aria-label=\"Tilføj billede\">\r\n </ds-icon-button>\r\n <ds-icon-button\r\n icon=\"remixAttachmentLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddAttachment()\"\r\n aria-label=\"Tilføj vedhæftning\">\r\n </ds-icon-button>\r\n \r\n <!-- Hidden file input for file selection -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"*/*\"\r\n multiple\r\n (change)=\"handleFileSelect($event)\"\r\n style=\"display: none;\"\r\n aria-hidden=\"true\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePostCreateBottomSheetComponent implements AfterViewInit, OnInit {\r\n @ViewChild('textareaInput') textareaInput?: ElementRef<HTMLTextAreaElement>;\r\n @ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;\r\n \r\n // Optional input to control auto-focus behavior\r\n autoFocus = true;\r\n \r\n // Control readonly state for keyboard trick\r\n isReadonly = true;\r\n \r\n // Edit mode properties - can be set via componentProps\r\n isEditMode = false;\r\n postId?: string;\r\n initialContent = '';\r\n \r\n postContent = '';\r\n selectedImages = signal<string[]>([]);\r\n username = signal('Lars Mikkelsen');\r\n placeholder = signal(\"Hvad er nyt?\");\r\n modalTitle = signal('Nyt opslag');\r\n submitButtonLabel = signal('Slå op');\r\n \r\n constructor(\r\n private modalController: ModalController,\r\n private elementRef: ElementRef\r\n ) {}\r\n \r\n /**\r\n * Ensure toolbar doesn't have unnecessary padding\r\n * Modal is already positioned below status bar, so no extra safe area needed\r\n */\r\n private applySafeAreaToToolbar(): void {\r\n try {\r\n const hostElement = this.elementRef?.nativeElement;\r\n if (hostElement) {\r\n const header = hostElement.querySelector('ion-header');\r\n if (header) {\r\n const toolbar = header.querySelector('ion-toolbar');\r\n if (toolbar) {\r\n const toolbarElement = toolbar as HTMLElement;\r\n // Ensure toolbar uses standard padding (no safe area since modal is already offset)\r\n toolbarElement.style.setProperty('--padding-top', '12px', 'important');\r\n toolbarElement.style.setProperty('--min-height', '56px', 'important');\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n console.log('[SafeArea] Failed to apply to toolbar:', e);\r\n }\r\n }\r\n \r\n ngOnInit(): void {\r\n // Initialize edit mode if provided\r\n if (this.isEditMode && this.initialContent) {\r\n this.postContent = this.initialContent;\r\n this.modalTitle.set('Rediger opslag');\r\n this.submitButtonLabel.set('Gem');\r\n }\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Apply safe area padding immediately to prevent corruption\r\n this.applySafeAreaToToolbar();\r\n \r\n // Auto-resize textarea if there's initial content (edit mode)\r\n if (this.postContent && this.textareaInput) {\r\n setTimeout(() => {\r\n this.resizeTextarea();\r\n }, 0);\r\n }\r\n \r\n // Try to focus IMMEDIATELY - no delay\r\n // This maximizes our chance of being in user gesture context\r\n if (this.autoFocus && this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Remove readonly immediately\r\n this.isReadonly = false;\r\n \r\n // Try focusing with minimal delay\r\n setTimeout(() => {\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // iOS sometimes needs a second attempt\r\n setTimeout(() => {\r\n textarea.focus();\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }, 100);\r\n }, 10);\r\n }\r\n }\r\n \r\n /**\r\n * Ionic lifecycle hook - called when modal enters view\r\n * At 95% height, this acts more like a page than a modal\r\n * which might allow keyboard to open\r\n */\r\n ionViewDidEnter(): void {\r\n // Resize textarea in case initial attempt didn't work\r\n if (this.postContent && this.textareaInput) {\r\n this.resizeTextarea();\r\n }\r\n \r\n // Final focus attempt when view fully enters\r\n if (this.autoFocus && this.textareaInput) {\r\n this.isReadonly = false;\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Try to focus as if this was a page navigation\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // Set cursor position\r\n const length = textarea.value.length;\r\n textarea.setSelectionRange(length, length);\r\n }\r\n }\r\n \r\n handleFocus(): void {\r\n // When user focuses (or we focus programmatically), remove readonly\r\n this.isReadonly = false;\r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }\r\n \r\n handleInput(): void {\r\n this.resizeTextarea();\r\n }\r\n \r\n /**\r\n * Auto-resize textarea based on content\r\n */\r\n private resizeTextarea(): void {\r\n if (this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n // Reset height to auto to get the correct scrollHeight\r\n textarea.style.height = 'auto';\r\n // Set height based on content, respecting min/max from CSS\r\n textarea.style.height = Math.min(textarea.scrollHeight, 400) + 'px';\r\n }\r\n }\r\n \r\n canPost(): boolean {\r\n return this.postContent.trim().length > 0 || this.selectedImages().length > 0;\r\n }\r\n \r\n async handleCancel(): Promise<void> {\r\n if (this.postContent.trim().length > 0 || this.selectedImages().length > 0) {\r\n // Show confirmation\r\n const confirmed = confirm('Kassér dette opslag?');\r\n if (confirmed) {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n } else {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n }\r\n \r\n async handlePost(): Promise<void> {\r\n if (!this.canPost()) return;\r\n \r\n if (this.isEditMode) {\r\n console.log('Updating post:', this.postId, this.postContent);\r\n } else {\r\n console.log('Creating post:', this.postContent, 'with images:', this.selectedImages().length);\r\n }\r\n \r\n // Pass the post content, images, and edit info back to the parent\r\n await this.modalController.dismiss(\r\n { \r\n content: this.postContent,\r\n images: this.selectedImages(),\r\n timestamp: new Date(),\r\n isEdit: this.isEditMode,\r\n postId: this.postId\r\n },\r\n 'post'\r\n );\r\n }\r\n \r\n async handleAddImage(): Promise<void> {\r\n console.log('Add image button clicked');\r\n \r\n // Re-apply safe area padding before opening camera (preventive)\r\n // This ensures the value is locked in before iOS corrupts it\r\n this.applySafeAreaToToolbar();\r\n \r\n try {\r\n console.log('Requesting photo from library...');\r\n \r\n const image = await Camera.getPhoto({\r\n quality: 90,\r\n allowEditing: false,\r\n resultType: CameraResultType.Uri,\r\n source: CameraSource.Photos, // Only show photo library, not camera\r\n });\r\n\r\n console.log('Photo selected successfully:', image);\r\n \r\n // Add the image path to the array\r\n if (image.webPath) {\r\n this.selectedImages.update(images => [...images, image.webPath!]);\r\n console.log('Image added to preview:', image.webPath);\r\n }\r\n \r\n // Re-apply safe area padding immediately after returning\r\n // Since we're using fixed values, this won't cause flickering\r\n requestAnimationFrame(() => {\r\n this.applySafeAreaToToolbar();\r\n });\r\n \r\n // Restore StatusBar configuration (background task)\r\n this.restoreStatusBar();\r\n \r\n } catch (error) {\r\n console.error('Photo selection error:', error);\r\n // Only show alert for non-cancellation errors\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const errorMessage = (error as any).message;\r\n if (!errorMessage.includes('cancel')) {\r\n alert(`Error selecting photo: ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Restore StatusBar configuration (background task)\r\n * Safe area padding is now handled preventively via applySafeAreaToToolbar()\r\n */\r\n private restoreStatusBar(): void {\r\n setTimeout(async () => {\r\n try {\r\n await StatusBar.setBackgroundColor({ color: '#221a4c' });\r\n await StatusBar.setOverlaysWebView({ overlay: false });\r\n } catch (e) {\r\n // StatusBar API not available, ignore\r\n }\r\n }, 0);\r\n }\r\n \r\n handleRemoveImage(index: number): void {\r\n console.log('Removing image at index:', index);\r\n this.selectedImages.update(images => images.filter((_, i) => i !== index));\r\n }\r\n \r\n handleAddAttachment(): void {\r\n console.log('Add attachment button clicked');\r\n // Trigger the hidden file input\r\n if (this.fileInput) {\r\n this.fileInput.nativeElement.click();\r\n }\r\n }\r\n \r\n handleFileSelect(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const files = input.files;\r\n \r\n if (!files || files.length === 0) {\r\n console.log('No files selected');\r\n return;\r\n }\r\n \r\n console.log('Files selected:', files.length);\r\n \r\n // Process each selected file\r\n Array.from(files).forEach(file => {\r\n console.log('File:', file.name, file.type, file.size);\r\n \r\n // Create a data URL for preview (for images and other files)\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const result = e.target?.result as string;\r\n if (result) {\r\n // Add to selectedImages array for preview\r\n this.selectedImages.update(images => [...images, result]);\r\n console.log('File added to preview:', file.name);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n \r\n // Reset the input so the same file can be selected again\r\n input.value = '';\r\n }\r\n}\r\n\r\n","import { Component, input, output, HostListener, ElementRef, ViewChild, AfterViewInit, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { \r\n IonHeader, \r\n IonToolbar, \r\n IonTitle,\r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent,\r\n Platform,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\nimport { DsMobileActionsBottomSheetComponent, ActionResult } from '../bottom-sheet';\r\n\r\n/**\r\n * DsMobilePageMainComponent\r\n * \r\n * A complete mobile page layout for main/tab pages with:\r\n * - Fixed header with logomark + title + avatar\r\n * - Purple expandable header section (scrolls with content)\r\n * - White rounded content wrapper\r\n * - Pull-to-refresh support\r\n * - Auto scroll title fade-in\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple page -->\r\n * <ds-mobile-page-main\r\n * title=\"Inquiries\"\r\n * [avatarInitials]=\"'JD'\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n * \r\n * <!-- Page with custom header content -->\r\n * <ds-mobile-page-main\r\n * title=\"Home\"\r\n * headerTitle=\"Welcome, Lars\"\r\n * headerSubtitle=\"Your rental property at a glance.\"\r\n * [avatarInitials]=\"'L'\">\r\n * \r\n * <div header-content class=\"property-tiles\">\r\n * <!-- Custom header content like tiles -->\r\n * </div>\r\n * \r\n * <div class=\"page-content\">\r\n * <!-- Main page content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-main',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-page-main.css'],\r\n template: `\r\n <!-- Fixed header at top -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-home\">\r\n <!-- Propbinder Logomark -->\r\n <svg class=\"logomark\" width=\"36\" height=\"32\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n \r\n <!-- Title - fades in on scroll -->\r\n <ion-title class=\"header-home__title\">{{ title() }}</ion-title>\r\n \r\n <!-- Avatar -->\r\n <div class=\"header-home__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n (click)=\"handleAvatarClick()\"\r\n style=\"cursor: pointer;\"\r\n />\r\n </div>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content with expandable header -->\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n <!-- Condensed header for Ionic scroll effects -->\r\n @if (showCondensedHeader()) {\r\n <ion-header collapse=\"condense\">\r\n <ion-toolbar>\r\n <ion-title size=\"large\">{{ title() }}</ion-title>\r\n </ion-toolbar>\r\n </ion-header>\r\n }\r\n\r\n <!-- Pull to refresh (only on native iOS/Android) -->\r\n @if (showRefresh() && isNativePlatform()) {\r\n <ion-refresher \r\n slot=\"fixed\" \r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\" \r\n [pullMin]=\"80\" \r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"remixArrowDownS\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <!-- Expandable header section (purple background) -->\r\n <div class=\"header-expandable\">\r\n <div class=\"header-expandable-inner\">\r\n <div class=\"header-expandable__text\">\r\n <h1 class=\"header-expandable__title\">{{ headerTitle() || title() }}</h1>\r\n @if (headerSubtitle()) {\r\n <p class=\"header-expandable__subtitle\">{{ headerSubtitle() }}</p>\r\n }\r\n </div>\r\n \r\n <!-- Slot for custom header content (e.g., property tiles) -->\r\n <ng-content select=\"[header-content]\"></ng-content>\r\n </div>\r\n </div>\r\n\r\n <!-- Content wrapper -->\r\n <div class=\"content-wrapper\">\r\n <div class=\"content-inner\">\r\n <!-- Main page content -->\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePageMainComponent extends MobilePageBase implements AfterViewInit {\r\n @ViewChild(IonContent) ionContent?: IonContent;\r\n \r\n // Platform detection\r\n private platform = inject(Platform);\r\n private modalController = inject(ModalController);\r\n private router = inject(Router);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n \r\n // Inputs - Title\r\n title = input.required<string>(); // For fixed header title\r\n headerTitle = input<string>(''); // Optional different title for expandable header\r\n headerSubtitle = input<string>('');\r\n \r\n // Inputs - Avatar\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n avatarInitials = input<string>('U');\r\n avatarSrc = input<string>('');\r\n avatarIconName = input<string>('remixUser3Line');\r\n \r\n // Inputs - Features\r\n showRefresh = input<boolean>(true);\r\n showCondensedHeader = input<boolean>(true);\r\n scrollThreshold = input<number>(160); // Pixels to scroll before title appears\r\n headerFadeDistance = input<number>(150); // Distance over which header fades out\r\n \r\n // Outputs\r\n avatarClick = output<void>();\r\n refresh = output<any>();\r\n scroll = output<any>();\r\n \r\n constructor(private elementRef: ElementRef) {\r\n super();\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial setup if needed\r\n }\r\n \r\n /**\r\n * Handle avatar click - opens profile actions bottom sheet\r\n */\r\n async handleAvatarClick(): Promise<void> {\r\n console.log('Avatar clicked - opening profile bottom sheet');\r\n \r\n // Emit the event for any parent listeners\r\n this.avatarClick.emit();\r\n \r\n const sheet = await this.modalController.create({\r\n component: DsMobileActionsBottomSheetComponent,\r\n componentProps: {\r\n customActionGroups: [\r\n {\r\n actions: [\r\n {\r\n action: 'profile',\r\n title: 'Min profil',\r\n icon: 'remixUser3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'settings',\r\n title: 'Indstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'whitelabel-demo',\r\n title: 'Whitelabel Demo',\r\n icon: 'remixPaletteLine',\r\n destructive: false\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'logout',\r\n title: 'Log ud',\r\n icon: 'remixLogoutBoxLine',\r\n destructive: true\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n // Auto-height: no breakpoints, no handle\r\n cssClass: 'ds-bottom-sheet auto-height'\r\n });\r\n \r\n await sheet.present();\r\n \r\n const result = await sheet.onWillDismiss<ActionResult>();\r\n if (result.data?.action) {\r\n console.log('Profile action selected:', result.data.action);\r\n \r\n switch (result.data.action) {\r\n case 'logout':\r\n console.log('Logging out...');\r\n // TODO: Implement logout logic\r\n break;\r\n case 'profile':\r\n console.log('Opening profile...');\r\n // TODO: Navigate to profile page\r\n break;\r\n case 'settings':\r\n console.log('Opening settings...');\r\n // TODO: Navigate to settings page\r\n break;\r\n case 'whitelabel-demo':\r\n console.log('Opening whitelabel demo...');\r\n this.router.navigate(['/whitelabel-demo']);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Handle scroll events\r\n * - Shows title in fixed header when scrolled past threshold\r\n * - Fades out expandable header content based on scroll position\r\n * - Emits scroll event for custom handling\r\n */\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop;\r\n const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');\r\n const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');\r\n \r\n // Show title in fixed header when scrolled past threshold\r\n if (scrollTop > this.scrollThreshold()) {\r\n header?.classList.add('header-scrolled');\r\n } else {\r\n header?.classList.remove('header-scrolled');\r\n }\r\n \r\n // Fade out header-expandable content based on scroll\r\n if (headerExpandable) {\r\n const fadeDistance = this.headerFadeDistance();\r\n const fadeProgress = Math.min(scrollTop / fadeDistance, 1);\r\n \r\n // Calculate opacity (1 to 0)\r\n const opacity = 1 - fadeProgress;\r\n \r\n // Calculate transform (0px to -20px upward)\r\n const translateY = fadeProgress * -20;\r\n \r\n // Apply styles\r\n headerExpandable.style.opacity = opacity.toString();\r\n headerExpandable.style.transform = `translateY(${translateY}px)`;\r\n }\r\n \r\n this.scroll.emit(event);\r\n }\r\n \r\n /**\r\n * Handle pull-to-refresh\r\n * Emits refresh event - parent should call event.target.complete()\r\n */\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n this.refresh.emit(event);\r\n }\r\n}\r\n\r\n","import { Component, input, output, ElementRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { IonHeader, IonToolbar, IonContent } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\n\r\n/**\r\n * DsMobilePageDetailsComponent\r\n * \r\n * A mobile page layout for detail/drill-down pages with:\r\n * - Back button header (mobile + desktop variants)\r\n * - White background content area\r\n * - Responsive padding\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple detail page -->\r\n * <ds-mobile-page-details\r\n * title=\"Property Details\"\r\n * (back)=\"goBack()\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * \r\n * <!-- With default back route -->\r\n * <ds-mobile-page-details\r\n * title=\"Invoice Details\"\r\n * backRoute=\"/invoices\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-details',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonContent,\r\n DsIconComponent\r\n ],\r\n styleUrls: ['./ds-mobile-page-details.css'],\r\n template: `\r\n <!-- Mobile header - hidden on desktop -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-back\">\r\n <button class=\"back-button\" (click)=\"handleBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftLine\" size=\"24px\" />\r\n </button>\r\n <h1 class=\"header-title\">{{ title() }}</h1>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <ion-content>\r\n <!-- Desktop header above content -->\r\n <div class=\"desktop-header\">\r\n <button class=\"back-button\" (click)=\"handleBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftLine\" size=\"24px\" />\r\n </button>\r\n <h1>{{ title() }}</h1>\r\n </div>\r\n\r\n <!-- Content area -->\r\n <div class=\"detail-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePageDetailsComponent extends MobilePageBase {\r\n // Inputs\r\n title = input.required<string>();\r\n backRoute = input<string>(''); // Optional default back route\r\n \r\n // Outputs\r\n back = output<void>();\r\n \r\n constructor(\r\n private navCtrl: NavController,\r\n private elementRef: ElementRef\r\n ) {\r\n super();\r\n }\r\n \r\n /**\r\n * Handle back navigation\r\n * \r\n * By default, navigates using the provided backRoute or browser back.\r\n * Parent components can listen to the (back) event to override this behavior.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default behavior: uses backRoute or browser back -->\r\n * <ds-mobile-page-details \r\n * title=\"Details\" \r\n * backRoute=\"/home\">\r\n * </ds-mobile-page-details>\r\n * \r\n * <!-- Custom behavior: parent handles navigation -->\r\n * <ds-mobile-page-details \r\n * title=\"Details\"\r\n * (back)=\"customBackHandler()\">\r\n * </ds-mobile-page-details>\r\n * ```\r\n */\r\n handleBack(): void {\r\n // Add class to trigger reverse animation\r\n this.elementRef.nativeElement.classList.add('navigating-back');\r\n \r\n // Emit event for parent to optionally handle\r\n this.back.emit();\r\n \r\n // Default behavior: navigate using backRoute or browser back\r\n if (this.backRoute()) {\r\n this.navCtrl.navigateBack(this.backRoute());\r\n } else {\r\n this.navCtrl.back();\r\n }\r\n }\r\n}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileContentComponent\r\n * \r\n * Main content container for mobile pages with flexible layout options.\r\n * Provides consistent spacing and layout patterns.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default: stacked layout -->\r\n * <ds-mobile-content>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * </ds-mobile-content>\r\n * \r\n * <!-- Grid layout -->\r\n * <ds-mobile-content layout=\"grid-2\">\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * </ds-mobile-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[class.layout-stacked]': 'layout() === \"stacked\"',\r\n '[class.layout-grid-2]': 'layout() === \"grid-2\"',\r\n '[class.layout-grid-3]': 'layout() === \"grid-3\"'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 32px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n \r\n /* Grid layouts */\r\n :host.layout-grid-2 {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 16px;\r\n }\r\n \r\n :host.layout-grid-3 {\r\n display: grid;\r\n grid-template-columns: repeat(3, 1fr);\r\n gap: 16px;\r\n }\r\n \r\n @media (max-width: 768px) {\r\n :host.layout-grid-2,\r\n :host.layout-grid-3 {\r\n grid-template-columns: 1fr;\r\n }\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class DsMobileContentComponent {\r\n /**\r\n * Layout mode for content sections\r\n * - 'stacked' - Vertical stack with 32px gap (default)\r\n * - 'grid-2' - 2 column grid\r\n * - 'grid-3' - 3 column grid (stacks on mobile)\r\n */\r\n layout = input<'stacked' | 'grid-2' | 'grid-3'>('stacked');\r\n}\r\n\r\n/**\r\n * DsMobileContentSectionComponent\r\n * \r\n * Section within mobile content with optional header.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-content-section>\r\n * <section-header width=\"half\"></section-header>\r\n * <content-row>\r\n * <div class=\"grey-box\"></div>\r\n * </content-row>\r\n * </ds-mobile-content-section>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-content-section',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"section-header\" />\r\n <ng-content />\r\n `\r\n})\r\nexport class DsMobileContentSectionComponent {}\r\n\r\n/**\r\n * SectionHeaderComponent\r\n * \r\n * Semantic placeholder header for content sections.\r\n * Used for prototyping/placeholders.\r\n */\r\n@Component({\r\n selector: 'section-header',\r\n standalone: true,\r\n host: {\r\n '[class.w-half]': 'width() === \"half\"',\r\n '[class.w-third]': 'width() === \"third\"',\r\n '[class.w-full]': 'width() === \"full\"'\r\n },\r\n styles: [`\r\n :host {\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-background-neutral-tertiary);\r\n display: block;\r\n }\r\n \r\n :host.w-half { width: 50%; }\r\n :host.w-third { width: 33%; }\r\n :host.w-full { width: 100%; }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class SectionHeaderComponent {\r\n /** Width of the header placeholder */\r\n width = input<'half' | 'third' | 'full'>('half');\r\n}\r\n\r\n/**\r\n * ContentRowComponent\r\n * \r\n * Horizontal row container for content items.\r\n */\r\n@Component({\r\n selector: 'content-row',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class ContentRowComponent {}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileHeaderContentComponent\r\n * \r\n * Container for header content tiles - displays tiles in a responsive grid.\r\n * Used within the expandable header section of mobile pages to show\r\n * summary information like property details, statistics, etc.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content header-content>\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Area</tile-label>\r\n * <tile-value>120 m²</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * </ds-mobile-header-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 12px;\r\n }\r\n \r\n @media (min-width: 768px) {\r\n :host {\r\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\r\n }\r\n }\r\n `],\r\n template: `<ng-content select=\"ds-mobile-header-content-tile\" />`\r\n})\r\nexport class DsMobileHeaderContentComponent {}\r\n\r\n/**\r\n * DsMobileHeaderContentTileComponent\r\n * \r\n * Individual tile for displaying summary information in the header.\r\n * Styled with purple background to match the mobile header theme.\r\n * \r\n * Must contain:\r\n * - `<tile-icon>` - Icon container (optional)\r\n * - `<tile-content>` - Label and value container\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" size=\"20px\" color=\"#DFE4FF\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Rooms</tile-label>\r\n * <tile-value>3 rooms</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content-tile',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n background: rgba(255, 255, 255, 0.05);\r\n border: 1px solid rgba(255, 255, 255, 0.1);\r\n border-radius: 12px;\r\n padding: 12px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-icon\" />\r\n <ng-content select=\"tile-content\" />\r\n `\r\n})\r\nexport class DsMobileHeaderContentTileComponent {}\r\n\r\n/**\r\n * TileIconComponent\r\n * \r\n * Semantic slot for tile icon with dark purple background.\r\n * Use within `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-icon',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n background: var(--color-brand-secondary);\r\n border-radius: 8px;\r\n width: 32px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileIconComponent {}\r\n\r\n/**\r\n * TileContentComponent\r\n * \r\n * Semantic slot for tile content containing label and value.\r\n * Use within `ds-mobile-header-content-tile`.\r\n * \r\n * Contains:\r\n * - `<tile-label>` - Small label text\r\n * - `<tile-value>` - Large value text\r\n */\r\n@Component({\r\n selector: 'tile-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n ::ng-deep tile-label {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(255, 255, 255, 0.8);\r\n display: block;\r\n }\r\n \r\n ::ng-deep tile-value {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: #ffffff;\r\n display: block;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-label\" />\r\n <ng-content select=\"tile-value\" />\r\n `\r\n})\r\nexport class TileContentComponent {}\r\n\r\n/**\r\n * TileLabelComponent\r\n * \r\n * Label text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-label',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(255, 255, 255, 0.8);\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileLabelComponent {}\r\n\r\n/**\r\n * TileValueComponent\r\n * \r\n * Value text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-value',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: #ffffff;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileValueComponent {}\r\n\r\n","import { Component, input, output, signal, model } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobilePostCardComponent\r\n * \r\n * Individual post card for community feed and post details.\r\n * Displays user posts with avatar, content, media, and action buttons.\r\n * Follows Threads-inspired design with clean layout and interactions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-post-card\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [clickable]=\"true\"\r\n * (postClick)=\"openPost()\">\r\n * \r\n * <post-content>\r\n * <post-text>This is a sample post...</post-text>\r\n * </post-content>\r\n * \r\n * <post-actions>\r\n * <action-like [active]=\"true\" count=\"42\" />\r\n * <action-comment count=\"12\" />\r\n * <action-share />\r\n * </post-actions>\r\n * </ds-mobile-post-card>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-card',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '[class.variant-feed]': 'variant() === \"feed\"',\r\n '[class.variant-detail]': 'variant() === \"detail\"',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '(click)': 'handlePostClick($event)',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-primary, #ffffff);\r\n padding: 8px;\r\n gap: 8px;\r\n transition: all 0.2s ease;\r\n position: relative;\r\n border-radius: 16px;\r\n margin-bottom: 8px;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n left: 52px;\r\n right: 8px;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:active {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n :host.variant-detail {\r\n padding: 0;\r\n margin-bottom: 8px;\r\n }\r\n \r\n :host.variant-detail::after {\r\n display: none;\r\n }\r\n \r\n :host.variant-compact {\r\n padding: 8px;\r\n gap: 8px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .post-header {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n /* Author styles imported from mobile-common.css */\r\n \r\n .menu-slot {\r\n margin-left: auto;\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n bottom: -6px;\r\n right: -6px;\r\n width: 20px;\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-brand-secondary, #5d5fef);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: 2px solid var(--color-background-primary, #ffffff);\r\n }\r\n \r\n .avatar-badge svg {\r\n width: 10px;\r\n position: relative;\r\n top: 1px;\r\n fill: white;\r\n }\r\n `],\r\n template: `\r\n <div class=\"post-header\">\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n @if (showBadge()) {\r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n }\r\n </div>\r\n \r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ authorName() }}</div>\r\n <div class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</div>\r\n </div>\r\n \r\n <div class=\"menu-slot\">\r\n <ng-content select=\"post-menu\" />\r\n </div>\r\n </div>\r\n \r\n <ng-content select=\"post-content\" />\r\n <ng-content select=\"post-actions\" />\r\n `\r\n})\r\nexport class DsMobilePostCardComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2h ago\", \"1d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Show badge on avatar (e.g., for property managers)\r\n */\r\n showBadge = input<boolean>(false);\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related posts\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the post card is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the post card is clicked (if clickable)\r\n */\r\n postClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when the post card is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n \r\n handlePostClick(event: Event): void {\r\n if (this.clickable()) {\r\n this.postClick.emit();\r\n }\r\n }\r\n \r\n handleCommentClick(): void {\r\n this.commentClick.emit();\r\n }\r\n \r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n // Don't start long press if touching action buttons or interactive elements\r\n const target = event.target as HTMLElement;\r\n if (target.closest('post-actions, action-like, action-comment, action-share, button, a, img')) {\r\n return;\r\n }\r\n \r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n \r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n \r\n // Haptic feedback for long press\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n \r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n \r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n \r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n/**\r\n * PostContentComponent\r\n * \r\n * Main content section of the post.\r\n * \r\n * Contains:\r\n * - `<post-text>` - Text content\r\n * - `<post-media>` - Optional images/videos\r\n * - `<post-attachments>` - Optional file attachments\r\n */\r\n@Component({\r\n selector: 'post-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n :host:not(.no-indent) {\r\n padding-left: 44px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"post-text\" />\r\n <ng-content select=\"post-media\" />\r\n <ng-content select=\"ds-mobile-inline-photo\" />\r\n <ng-content select=\"post-attachments\" />\r\n `\r\n})\r\nexport class PostContentComponent {}\r\n\r\n/**\r\n * PostTextComponent\r\n * \r\n * Text content of the post.\r\n */\r\n@Component({\r\n selector: 'post-text',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n display: block;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostTextComponent {}\r\n\r\n/**\r\n * PostMediaComponent\r\n * \r\n * Media container for images/videos.\r\n */\r\n@Component({\r\n selector: 'post-media',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: block;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n ::ng-deep img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n ::ng-deep video {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostMediaComponent {}\r\n\r\n/**\r\n * PostAttachmentsComponent\r\n * \r\n * Container for file attachments, links, etc.\r\n */\r\n@Component({\r\n selector: 'post-attachments',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostAttachmentsComponent {}\r\n\r\n/**\r\n * PostActionsComponent\r\n * \r\n * Action buttons container (like, comment, share).\r\n * \r\n * Contains:\r\n * - `<action-like>` - Like button with count\r\n * - `<action-comment>` - Comment button with count\r\n * - `<action-share>` - Share button\r\n */\r\n@Component({\r\n selector: 'post-actions',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding-top: 4px;\r\n }\r\n \r\n :host:not(.no-indent) {\r\n padding-left: 44px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostActionsComponent {}\r\n\r\n/**\r\n * ActionLikeComponent\r\n * \r\n * Like action button with count display and animated heart icon.\r\n */\r\n@Component({\r\n selector: 'action-like',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.active]': 'active()',\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n #pulseIcon\r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n <ds-icon \r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n </div>\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionLikeComponent {\r\n /**\r\n * Whether the like is active (user has liked)\r\n * Using model() for two-way binding\r\n */\r\n active = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n * Using model() for two-way binding\r\n */\r\n count = model<number>(0);\r\n \r\n /**\r\n * Emits when the like button is clicked\r\n */\r\n likeClick = output<{ active: boolean; count: number }>();\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n async handleClick(event: Event): Promise<void> {\r\n event.stopPropagation();\r\n \r\n // Toggle active state\r\n const newActive = !this.active();\r\n this.active.set(newActive);\r\n \r\n // Update count\r\n const newCount = newActive ? this.count() + 1 : this.count() - 1;\r\n this.count.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newActive) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n // Emit the event with the new state\r\n this.likeClick.emit({ active: newActive, count: newCount });\r\n }\r\n}\r\n\r\n/**\r\n * ActionCommentComponent\r\n * \r\n * Comment action button with count display.\r\n */\r\n@Component({\r\n selector: 'action-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n :host:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <ds-icon name=\"remixChat3Line\" size=\"20px\" />\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionCommentComponent {\r\n /**\r\n * Number of comments\r\n */\r\n count = input<number>(0);\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.commentClick.emit();\r\n }\r\n}\r\n","import { Component, input, output, model, signal, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileCommentComponent\r\n * \r\n * Individual comment component for post discussions.\r\n * Displays user comments with avatar, content, and like action.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-comment\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'1h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [content]=\"'Great post!'\">\r\n * </ds-mobile-comment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent, DsIconButtonComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleCommentClick($event)',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n padding: 8px;\r\n position: relative;\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n background: var(--color-background-primary, #ffffff);\r\n margin-bottom: 8px;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n :host:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n /* Align with comment content: padding (8px) + avatar (32px) + gap (12px) */\r\n left: 44px;\r\n /* Align with comment content right edge: padding (8px) from right */\r\n right: 8px;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:active {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n \r\n .comment-content {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n \r\n .comment-header {\r\n display: flex;\r\n align-items: baseline;\r\n gap: 6px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n /* Wrapper for like and more actions */\r\n .header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin-left: auto;\r\n }\r\n \r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button {\r\n display: none; /* Hidden by default (mobile) */\r\n }\r\n \r\n /* Make button circular */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Show only on desktop with hover capability */\r\n @media (hover: hover) and (pointer: fine) {\r\n .desktop-more-button {\r\n display: block;\r\n }\r\n }\r\n \r\n /* Author styles imported from mobile-common.css */\r\n \r\n .action-like {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 18px;\r\n }\r\n \r\n .like-count {\r\n opacity: 1;\r\n }\r\n \r\n .like-count.hidden {\r\n opacity: 0;\r\n }\r\n \r\n .action-like.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .comment-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n \r\n .comment-text ::ng-deep .mention {\r\n color: var(--color-brand-base, #6B5FF5) !important;\r\n font-weight: 600;\r\n }\r\n \r\n .comment-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n margin-top: 4px;\r\n }\r\n \r\n .action-reply {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .action-reply:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .action-edit {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .action-edit:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n `],\r\n template: `\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n size=\"sm\" />\r\n </div>\r\n \r\n <div class=\"comment-content\">\r\n <div class=\"comment-header\">\r\n <span class=\"author-name\">{{ authorName() }}</span>\r\n <span class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</span>\r\n \r\n <!-- Wrapper for like and more actions -->\r\n <div class=\"header-actions\">\r\n <div \r\n class=\"action-like\"\r\n [class.active]=\"isLiked()\"\r\n (click)=\"toggleLike()\">\r\n <span class=\"like-count\" [class.hidden]=\"likeCount() === 0\">{{ likeCount() }}</span>\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"16px\" />\r\n <ds-icon \r\n [name]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"16px\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Desktop more button -->\r\n <ds-icon-button\r\n class=\"desktop-more-button\"\r\n icon=\"remixMoreFill\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleMoreButtonClick($event)\"\r\n aria-label=\"More options\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"comment-text\" [innerHTML]=\"formattedContent()\"></div>\r\n \r\n <div class=\"comment-actions\">\r\n <div class=\"action-reply\" (click)=\"handleReply()\">\r\n Reply\r\n </div>\r\n @if (isOwnComment()) {\r\n <div class=\"action-edit\" (click)=\"handleEdit()\">\r\n Edit\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileCommentComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"1h ago\", \"2d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Comment content text\r\n */\r\n content = input.required<string>();\r\n \r\n /**\r\n * Avatar initials\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Whether the comment is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Whether this comment belongs to the current user\r\n */\r\n isOwnComment = input<boolean>(false);\r\n \r\n /**\r\n * Whether the comment is liked by current user\r\n */\r\n isLiked = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n */\r\n likeCount = model<number>(0);\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n /**\r\n * Computed property to format content with @mentions\r\n */\r\n formattedContent = computed(() => {\r\n const text = this.content();\r\n // Replace @mentions with styled spans\r\n // Matches @FirstName or @FirstName LastName (max 2 words)\r\n return text.replace(/@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\b/g, '<span class=\"mention\">@$1</span>');\r\n });\r\n \r\n /**\r\n * Emits when the comment card is clicked (if clickable)\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when reply is clicked\r\n */\r\n replyClick = output<void>();\r\n \r\n /**\r\n * Emits when edit is clicked\r\n */\r\n editClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n \r\n handleCommentClick(event: Event): void {\r\n // Only emit if clickable and not clicking on action buttons\r\n if (this.clickable() && !(event.target as HTMLElement).closest('.comment-actions')) {\r\n this.commentClick.emit();\r\n }\r\n }\r\n \r\n async toggleLike(): Promise<void> {\r\n const newLiked = !this.isLiked();\r\n this.isLiked.set(newLiked);\r\n \r\n const newCount = newLiked ? this.likeCount() + 1 : this.likeCount() - 1;\r\n this.likeCount.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newLiked) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }\r\n \r\n handleReply(): void {\r\n this.replyClick.emit();\r\n }\r\n \r\n handleEdit(): void {\r\n this.editClick.emit();\r\n }\r\n \r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n \r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n \r\n // Haptic feedback for long press\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n \r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n \r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n \r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n \r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation and triggers long press action\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n console.log('[Comment] Desktop more button clicked');\r\n event.stopPropagation();\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobilePostComposerComponent\r\n * \r\n * A \"fake\" input composer for creating new posts in the community feed.\r\n * Features a user avatar, placeholder input, and post button.\r\n * Clicking opens the full post creation modal/page.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-post-composer\r\n * [avatarInitials]=\"'LM'\"\r\n * [avatarType]=\"'photo'\"\r\n * [avatarSrc]=\"'...'\"\r\n * (composerClick)=\"openPostCreator()\">\r\n * </ds-mobile-post-composer>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-composer',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent],\r\n host: {\r\n '(click)': 'handleClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n max-width: 640px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n .composer-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .composer-input-wrapper {\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .composer-input {\r\n width: 100%;\r\n background: rgba(255, 255, 255, 0.1);\r\n border: none;\r\n border-radius: 24px;\r\n padding: 10px 16px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: rgba(255, 255, 255, 0.5);\r\n outline: none;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n pointer-events: none;\r\n user-select: none;\r\n }\r\n \r\n .composer-input::placeholder {\r\n color: rgba(255, 255, 255, 0.5);\r\n opacity: 1;\r\n }\r\n \r\n /* Hover effects for desktop */\r\n @media (hover: hover) {\r\n :host:hover .composer-input {\r\n opacity: 0.8;\r\n }\r\n }\r\n `],\r\n template: `\r\n <div class=\"composer-container\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n <div class=\"composer-input-wrapper\">\r\n <input \r\n type=\"text\" \r\n class=\"composer-input\" \r\n [placeholder]=\"placeholder()\"\r\n readonly\r\n tabindex=\"-1\"\r\n />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobilePostComposerComponent {\r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Placeholder text for the input\r\n */\r\n placeholder = input<string>(\"Hvad er nyt?\");\r\n \r\n /**\r\n * Text for the post button\r\n */\r\n buttonText = input<string>('Slå op');\r\n \r\n /**\r\n * Emits when the composer is clicked\r\n */\r\n composerClick = output<void>();\r\n \r\n handleClick(): void {\r\n this.composerClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output, signal, model } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemPostComponent\r\n * \r\n * Specialized interactive list item for displaying social media posts.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays user posts with avatar, content, media, and action buttons.\r\n * Follows Threads-inspired design with clean layout and interactions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-post\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [clickable]=\"true\"\r\n * (postClick)=\"openPost()\">\r\n * \r\n * <post-content>\r\n * <post-text>This is a sample post...</post-text>\r\n * </post-content>\r\n * \r\n * <post-actions>\r\n * <action-like [active]=\"true\" count=\"42\" />\r\n * <action-comment count=\"12\" />\r\n * </post-actions>\r\n * </ds-mobile-interactive-list-item-post>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-post',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsMobileListItemComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .post-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n height: 32px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .author-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .author-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-tertiary, #626B78);\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n bottom: -6px;\r\n right: -6px;\r\n width: 20px;\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-brand-secondary, #5d5fef);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: 2px solid var(--color-background-primary, #ffffff);\r\n }\r\n \r\n .avatar-badge svg {\r\n width: 10px;\r\n position: relative;\r\n top: 1px;\r\n fill: white;\r\n }\r\n \r\n .menu-slot {\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handlePostClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n @if (showBadge()) {\r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"post-header\">\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ authorName() }}</div>\r\n <div class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</div>\r\n </div>\r\n \r\n <div class=\"menu-slot\">\r\n <ng-content select=\"post-menu\" />\r\n </div>\r\n </div>\r\n \r\n <ng-content select=\"post-content\" />\r\n <ng-content select=\"post-actions\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemPostComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2h ago\", \"1d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Show badge on avatar (e.g., for property managers)\r\n */\r\n showBadge = input<boolean>(false);\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related posts\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the post card is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the post card is clicked (if clickable)\r\n */\r\n postClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when the post card is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handlePostClick(): void {\r\n console.log('[InteractiveListItemPost] handlePostClick called, emitting postClick');\r\n this.postClick.emit();\r\n }\r\n \r\n handleCommentClick(): void {\r\n this.commentClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n/**\r\n * PostContentComponent\r\n * \r\n * Main content section of the post.\r\n * \r\n * Contains:\r\n * - `<post-text>` - Text content\r\n * - `<post-media>` - Optional images/videos\r\n * - `<post-attachments>` - Optional file attachments\r\n */\r\n@Component({\r\n selector: 'post-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n margin-bottom: 8px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"post-text\" />\r\n <ng-content select=\"post-media\" />\r\n <ng-content select=\"ds-mobile-inline-photo\" />\r\n <ng-content select=\"post-attachments\" />\r\n `\r\n})\r\nexport class PostContentComponent {}\r\n\r\n/**\r\n * PostTextComponent\r\n * \r\n * Text content of the post.\r\n */\r\n@Component({\r\n selector: 'post-text',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n display: block;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostTextComponent {}\r\n\r\n/**\r\n * PostMediaComponent\r\n * \r\n * Media container for images/videos.\r\n */\r\n@Component({\r\n selector: 'post-media',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: block;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n ::ng-deep img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n ::ng-deep video {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostMediaComponent {}\r\n\r\n/**\r\n * PostAttachmentsComponent\r\n * \r\n * Container for file attachments, links, etc.\r\n */\r\n@Component({\r\n selector: 'post-attachments',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostAttachmentsComponent {}\r\n\r\n/**\r\n * PostActionsComponent\r\n * \r\n * Action buttons container (like, comment, share).\r\n * \r\n * Contains:\r\n * - `<action-like>` - Like button with count\r\n * - `<action-comment>` - Comment button with count\r\n * - `<action-share>` - Share button\r\n */\r\n@Component({\r\n selector: 'post-actions',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding-top: 4px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostActionsComponent {}\r\n\r\n/**\r\n * ActionLikeComponent\r\n * \r\n * Like action button with count display and animated heart icon.\r\n */\r\n@Component({\r\n selector: 'action-like',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.active]': 'active()',\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n #pulseIcon\r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n <ds-icon \r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n </div>\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionLikeComponent {\r\n /**\r\n * Whether the like is active (user has liked)\r\n * Using model() for two-way binding\r\n */\r\n active = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n * Using model() for two-way binding\r\n */\r\n count = model<number>(0);\r\n \r\n /**\r\n * Emits when the like button is clicked\r\n */\r\n likeClick = output<{ active: boolean; count: number }>();\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n async handleClick(event: Event): Promise<void> {\r\n event.stopPropagation();\r\n \r\n // Toggle active state\r\n const newActive = !this.active();\r\n this.active.set(newActive);\r\n \r\n // Update count\r\n const newCount = newActive ? this.count() + 1 : this.count() - 1;\r\n this.count.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newActive) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n // Emit the event with the new state\r\n this.likeClick.emit({ active: newActive, count: newCount });\r\n }\r\n}\r\n\r\n/**\r\n * ActionCommentComponent\r\n * \r\n * Comment action button with count display.\r\n */\r\n@Component({\r\n selector: 'action-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n :host:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <ds-icon name=\"remixChat3Line\" size=\"20px\" />\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionCommentComponent {\r\n /**\r\n * Number of comments\r\n */\r\n count = input<number>(0);\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.commentClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * PostPdfAttachmentComponent\r\n * \r\n * PDF file attachment display for posts.\r\n * Shows PDF info card with icon, filename, and file size.\r\n * Emits click event to open PDF in viewer.\r\n */\r\n@Component({\r\n selector: 'post-pdf-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .pdf-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .pdf-avatar::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .pdf-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .pdf-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .pdf-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"pdf-avatar\">\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"pdf-info\">\r\n <div class=\"pdf-name\">{{ fileName() }}</div>\r\n <div class=\"pdf-meta\">PDF · {{ fileSize() }}</div>\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"24px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class PostPdfAttachmentComponent {\r\n /**\r\n * PDF file name\r\n */\r\n fileName = input<string>('Document.pdf');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * Emits when the PDF attachment is clicked\r\n */\r\n pdfClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.pdfClick.emit();\r\n }\r\n}\r\n\r\n","// Export the main component and shared post components without the indent\r\nexport {\r\n DsMobileInteractiveListItemPostComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from './ds-mobile-interactive-list-item-post';\r\nexport { PostPdfAttachmentComponent } from './ds-mobile-post-pdf-attachment';\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsShapeIndicatorComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemInquiryComponent\r\n * \r\n * Specialized interactive list item for displaying inquiries/tickets.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays inquiry title, description, status, and timestamp.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-inquiry\r\n * [title]=\"'Tumble dryer is not working'\"\r\n * [description]=\"'For the past three days, I have been experiencing...'\"\r\n * [status]=\"'open'\"\r\n * [timestamp]=\"'12 days ago'\"\r\n * [iconName]=\"'remixCalendarLine'\"\r\n * [clickable]=\"true\"\r\n * (inquiryClick)=\"openInquiry()\">\r\n * </ds-mobile-interactive-list-item-inquiry>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-inquiry',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsShapeIndicatorComponent, DsMobileListItemComponent],\r\n styleUrls: ['./ds-mobile-interactive-list-item-inquiry.css'],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .inquiry-icon {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 8px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n \r\n .inquiry-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .inquiry-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .inquiry-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n \r\n .inquiry-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-top: 4px;\r\n }\r\n \r\n .inquiry-status {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-status.open {\r\n color: var(--color-brand-primary, #5d5fef);\r\n }\r\n \r\n .inquiry-status.closed {\r\n color: var(--text-color-default-tertiary, #737373);\r\n }\r\n \r\n .inquiry-timestamp {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handleInquiryClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"inquiry-icon\">\r\n <ds-icon \r\n [name]=\"iconName()\"\r\n size=\"20px\"\r\n [color]=\"iconColor()\" />\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"inquiry-content\">\r\n <h3 class=\"inquiry-title\">{{ title() }}</h3>\r\n \r\n @if (description()) {\r\n <p class=\"inquiry-description\">{{ description() }}</p>\r\n }\r\n \r\n <div class=\"inquiry-meta\">\r\n <div class=\"inquiry-status\" [class.open]=\"status() === 'open'\" [class.closed]=\"status() === 'closed'\">\r\n <ds-shape-indicator \r\n shape=\"circle\" \r\n [variant]=\"status() === 'open' ? 'brand' : 'grey'\">\r\n </ds-shape-indicator>\r\n <span>{{ computedStatusLabel() }}</span>\r\n </div>\r\n \r\n <div class=\"inquiry-timestamp\">\r\n <ds-icon name=\"remixTimeLine\" size=\"14px\" color=\"--color-text-secondary\" />\r\n <span>{{ timestamp() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div content-trailing>\r\n <div class=\"inquiry-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n </div>\r\n }\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemInquiryComponent {\r\n /**\r\n * Inquiry title\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Inquiry description/preview text\r\n */\r\n description = input<string>('');\r\n \r\n /**\r\n * Inquiry status\r\n */\r\n status = input<'open' | 'closed'>('open');\r\n \r\n /**\r\n * Status label (defaults to capitalized status)\r\n */\r\n statusLabel = input<string>('');\r\n \r\n /**\r\n * Timestamp text (e.g., \"12 days ago\", \"2 months ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Icon name for the leading icon\r\n */\r\n iconName = input<string>('remixTodoLine');\r\n \r\n /**\r\n * Icon color\r\n */\r\n iconColor = input<string>('secondary');\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the inquiry item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the inquiry item is clicked (if clickable)\r\n */\r\n inquiryClick = output<void>();\r\n \r\n /**\r\n * Emits when the inquiry item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Get computed status label\r\n */\r\n computedStatusLabel(): string {\r\n if (this.statusLabel()) {\r\n return this.statusLabel();\r\n }\r\n return this.status() === 'open' ? 'Åben' : 'Lukket';\r\n }\r\n \r\n handleInquiryClick(): void {\r\n this.inquiryClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemMessageComponent\r\n * \r\n * Specialized interactive list item for displaying message threads.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays message preview with sender info - simplified version without actions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-message\r\n * [senderName]=\"'John Doe'\"\r\n * [senderRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [message]=\"'Hey, when is the maintenance scheduled?'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [unread]=\"true\"\r\n * [clickable]=\"true\"\r\n * (messageClick)=\"openThread()\">\r\n * </ds-mobile-interactive-list-item-message>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-message',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsMobileListItemComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .message-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n }\r\n \r\n .sender-details {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .sender-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 0;\r\n }\r\n \r\n .sender-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-tertiary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 1;\r\n }\r\n \r\n .unread-indicator {\r\n width: 8px;\r\n height: 8px;\r\n border-radius: 50%;\r\n background: var(--color-brand-primary, #5d5fef);\r\n flex-shrink: 0;\r\n }\r\n \r\n .message-preview {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"'feed'\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handleMessageClick()\"\r\n (longPress)=\"handleLongPress()\">\r\n \r\n <div content-leading>\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n size=\"md\" />\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"message-header\">\r\n <div class=\"sender-details\">\r\n <span class=\"sender-name\">{{ senderName() }}</span>\r\n <span class=\"sender-meta\">{{ senderRole() }}</span>\r\n </div>\r\n \r\n @if (unread()) {\r\n <div class=\"unread-indicator\"></div>\r\n }\r\n </div>\r\n \r\n <p class=\"message-preview\">{{ message() }}</p>\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemMessageComponent {\r\n /**\r\n * Sender's display name\r\n */\r\n senderName = input.required<string>();\r\n \r\n /**\r\n * Sender's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n senderRole = input.required<string>();\r\n \r\n /**\r\n * Message preview text\r\n */\r\n message = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Whether the message is unread\r\n */\r\n unread = input<boolean>(false);\r\n \r\n /**\r\n * Whether the message item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the message item is clicked\r\n */\r\n messageClick = output<void>();\r\n \r\n /**\r\n * Emits when the message item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handleMessageClick(): void {\r\n this.messageClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileContactListItemComponent\r\n * \r\n * Specialized interactive component for displaying contacts.\r\n * Displays contact name with avatar initials and metadata (person name + phone number).\r\n * Similar styling to file attachments with rounded corners and hover states.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-contact-list-item\r\n * [name]=\"'Mortensen & Søn ApS'\"\r\n * [initials]=\"'M'\"\r\n * [contactPerson]=\"'John Mortensen'\"\r\n * [phoneNumber]=\"'+45 12 34 56 78'\"\r\n * [clickable]=\"true\"\r\n * (contactClick)=\"openContact()\">\r\n * </ds-mobile-contact-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-contact-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsAvatarComponent],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleContactClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host.clickable:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .contact-avatar {\r\n flex-shrink: 0;\r\n }\r\n\r\n .contact-content {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .contact-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .contact-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin: 0;\r\n }\r\n \r\n .meta-separator {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n \r\n .contact-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"contact-avatar\">\r\n <ds-avatar\r\n [initials]=\"initials()\"\r\n type=\"initials\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"contact-content\">\r\n <div class=\"contact-name\">{{ name() }}</div>\r\n \r\n @if (contactPerson() || phoneNumber()) {\r\n <div class=\"contact-meta\">\r\n @if (contactPerson()) {\r\n <span>{{ contactPerson() }}</span>\r\n }\r\n @if (contactPerson() && phoneNumber()) {\r\n <span class=\"meta-separator\">·</span>\r\n }\r\n @if (phoneNumber()) {\r\n <span>{{ phoneNumber() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div class=\"contact-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n }\r\n `\r\n})\r\nexport class DsMobileContactListItemComponent {\r\n /**\r\n * Contact/company name\r\n */\r\n name = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (usually 1-2 letters)\r\n */\r\n initials = input.required<string>();\r\n \r\n /**\r\n * Contact person name (optional)\r\n */\r\n contactPerson = input<string>('');\r\n \r\n /**\r\n * Phone number (optional)\r\n */\r\n phoneNumber = input<string>('');\r\n \r\n /**\r\n * Whether the contact item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the contact item is clicked (if clickable)\r\n */\r\n contactClick = output<void>();\r\n \r\n handleContactClick(): void {\r\n if (this.clickable()) {\r\n this.contactClick.emit();\r\n }\r\n }\r\n}\r\n\r\n","import { Component, ElementRef, signal, ViewChild, AfterViewInit, input, output, effect, Injector, computed, inject } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';\r\nimport { \r\n IonTabs, \r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel,\r\n IonHeader, \r\n IonToolbar, \r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent,\r\n Platform\r\n} from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\nexport type HeaderVariant = 'home' | 'simple' | 'back' | 'none';\r\n\r\n/**\r\n * DsMobileAppLayoutComponent\r\n * \r\n * A complete mobile application shell component based on actual mobile page patterns.\r\n * Provides tab navigation, flexible headers, and mobile-optimized layout.\r\n * \r\n * Features:\r\n * - Tab bar navigation with active state\r\n * - Multiple header variants (home with logomark, simple title, back button)\r\n * - Pull-to-refresh support\r\n * - Purple brand background with content wrapper\r\n * - iOS safe area support\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-app-layout\r\n * [showTabBar]=\"true\"\r\n * [tabs]=\"tabsConfig\"\r\n * [headerVariant]=\"'home'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-app-layout',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonTabs,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n IonHeader,\r\n IonToolbar,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-app-layout.css'],\r\n template: `\r\n @if (showTabBar()) {\r\n <!-- Layout with tab bar - NO ion-content, pages provide their own -->\r\n <ion-tabs>\r\n <!-- Tab Bar - dynamic slot based on viewport -->\r\n <ion-tab-bar [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\">\r\n @for (tab of tabs(); track tab.id) {\r\n <ion-tab-button \r\n [tab]=\"tab.id\" \r\n (click)=\"navigateToTab(tab.route)\">\r\n <ds-icon \r\n [name]=\"isTabActive(tab.id) ? tab.iconActive : tab.icon\" \r\n size=\"24px\" \r\n />\r\n <ion-label>{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n }\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n } @else {\r\n <!-- Standalone layout (no tabs) -->\r\n @if (headerVariant() !== 'none') {\r\n <ion-header>\r\n <ion-toolbar>\r\n @switch (headerVariant()) {\r\n @case ('home') {\r\n <div class=\"header-home\">\r\n <svg class=\"logomark\" width=\"36\" height=\"32\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n <div class=\"header-home__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n (click)=\"handleAvatarClick()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n @case ('back') {\r\n <div class=\"header-back\">\r\n @if (showBackButton()) {\r\n <button class=\"back-button\" (click)=\"handleBackClick()\">\r\n <ds-icon name=\"remixArrowLeftSLine\" size=\"24px\" />\r\n </button>\r\n }\r\n <h1 class=\"header-title\">{{ pageTitle() }}</h1>\r\n </div>\r\n }\r\n @case ('simple') {\r\n <div class=\"header-simple\">\r\n <h1 class=\"header-title\">{{ pageTitle() }}</h1>\r\n </div>\r\n }\r\n }\r\n </ion-toolbar>\r\n </ion-header>\r\n }\r\n\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n @if (showPullToRefresh() && isNativePlatform()) {\r\n <ion-refresher\r\n slot=\"fixed\"\r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\"\r\n [pullMin]=\"80\"\r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"remixArrowDownS\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <ng-content></ng-content>\r\n </ion-content>\r\n }\r\n `\r\n})\r\nexport class DsMobileAppLayoutComponent implements AfterViewInit {\r\n @ViewChild(IonContent, { static: false }) ionContent!: IonContent;\r\n\r\n // Platform detection\r\n private platform = inject(Platform);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n\r\n // Inputs\r\n headerVariant = input<HeaderVariant>('simple');\r\n pageTitle = input<string>('');\r\n showBackButton = input<boolean>(false);\r\n showPullToRefresh = input<boolean>(false);\r\n showTabBar = input<boolean>(false);\r\n tabs = input<TabConfig[]>([]);\r\n \r\n // Avatar inputs (for home header)\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n avatarInitials = input<string>('U');\r\n avatarSrc = input<string>('');\r\n avatarIconName = input<string>('remixUser3Line');\r\n\r\n // Outputs\r\n backClick = output<void>();\r\n refresh = output<any>();\r\n avatarClick = output<void>();\r\n scroll = output<any>();\r\n\r\n // Internal state\r\n private scrollY = signal(0);\r\n activeTab = signal<string>('home');\r\n isDesktop = signal<boolean>(false);\r\n\r\n constructor(\r\n private router: Router,\r\n private elementRef: ElementRef,\r\n private breakpointObserver: BreakpointObserver\r\n ) {\r\n // Track active tab based on current route\r\n this.router.events.subscribe(() => {\r\n const url = this.router.url;\r\n const tab = this.tabs().find(t => url.includes(t.route));\r\n if (tab) {\r\n this.activeTab.set(tab.id);\r\n }\r\n });\r\n \r\n // Track breakpoint for tab bar positioning\r\n this.breakpointObserver.observe(['(min-width: 768px)'])\r\n .subscribe(result => {\r\n this.isDesktop.set(result.matches);\r\n });\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n if (this.ionContent) {\r\n this.ionContent.scrollEvents = true;\r\n this.ensureScrollable();\r\n }\r\n }\r\n\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop || 0;\r\n this.scrollY.set(scrollTop);\r\n this.scroll.emit(event);\r\n }\r\n\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n this.refresh.emit(event);\r\n // Note: Parent component should handle event.target.complete()\r\n // If no handler is provided, you can add a default timeout in the parent\r\n }\r\n\r\n handleBackClick(): void {\r\n this.backClick.emit();\r\n }\r\n\r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n\r\n navigateToTab(route: string): void {\r\n this.router.navigateByUrl(route, { replaceUrl: true });\r\n }\r\n\r\n private ensureScrollable(): void {\r\n if (this.ionContent) {\r\n this.ionContent.getScrollElement().then((scrollEl: HTMLElement) => {\r\n if (scrollEl) {\r\n scrollEl.style.overscrollBehaviorY = 'none';\r\n (scrollEl.style as any).webkitOverflowScrolling = 'touch';\r\n }\r\n });\r\n }\r\n }\r\n\r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n}\r\n\r\n","import { Component, Input, Output, EventEmitter, signal, OnInit, AfterViewInit, ElementRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RouterLink, RouterLinkActive } from '@angular/router';\r\nimport { \r\n IonTabs, \r\n IonTab,\r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\n/**\r\n * DsMobileTabsComponent\r\n * \r\n * Responsive tab navigation that adapts from mobile to desktop:\r\n * - Mobile (< 768px): Bottom tab bar with icons + labels\r\n * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar\r\n * \r\n * Wraps ion-tabs to maintain native routing functionality while\r\n * providing a responsive navigation experience with branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tabs\r\n * [tabs]=\"tabsConfig\"\r\n * [avatarInitials]=\"'JD'\"\r\n * (avatarClick)=\"handleAvatarClick()\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tabs',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n RouterLink,\r\n RouterLinkActive,\r\n IonTabs,\r\n IonTab,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-tabs.css'],\r\n template: `\r\n <ion-tabs>\r\n <ng-container *ngIf=\"tabs && tabs.length > 0\">\r\n <ion-tab *ngFor=\"let tab of tabs; trackBy: trackByTabId\" [tab]=\"tab.id\"></ion-tab>\r\n </ng-container>\r\n \r\n <ion-tab-bar \r\n [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\" \r\n class=\"ds-tab-bar\"\r\n [class.ds-tab-bar--desktop]=\"isDesktop()\">\r\n \r\n <!-- Logo (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__logo\">\r\n <svg class=\"logomark\" width=\"32\" height=\"28\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n \r\n <!-- Tab buttons container -->\r\n <div class=\"ds-tab-bar__tabs\" *ngIf=\"tabs\">\r\n <ion-tab-button \r\n *ngFor=\"let tab of tabs; trackBy: trackByTabId\"\r\n [tab]=\"tab.id\"\r\n [routerLink]=\"['/', tab.route]\"\r\n routerLinkActive=\"tab-selected\"\r\n [routerLinkActiveOptions]=\"{ exact: false }\"\r\n [attr.data-icon]=\"tab.icon\"\r\n [attr.data-icon-active]=\"tab.iconActive\"\r\n [attr.aria-label]=\"tab.label\"\r\n class=\"ds-tab-button ion-activatable\"\r\n [class.tab-selected]=\"isTabActive(tab.id)\">\r\n <div class=\"tab-icon-ripple\"></div>\r\n <div class=\"tab-icon-wrapper\">\r\n <ds-icon \r\n [name]=\"tab.icon\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-inactive\"\r\n />\r\n <ds-icon \r\n [name]=\"tab.iconActive\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-active\"\r\n />\r\n </div>\r\n <ion-label [attr.aria-hidden]=\"true\">{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n </div>\r\n \r\n <!-- Avatar (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType\"\r\n [initials]=\"avatarInitials\"\r\n [src]=\"avatarSrc\"\r\n [iconName]=\"avatarIconName\"\r\n (click)=\"handleAvatarClick()\"\r\n />\r\n </div>\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n `\r\n})\r\nexport class DsMobileTabsComponent implements OnInit, AfterViewInit {\r\n // Inputs\r\n @Input() tabs: TabConfig[] = [];\r\n \r\n // Avatar inputs\r\n @Input() avatarType: 'initials' | 'photo' | 'icon' = 'initials';\r\n @Input() avatarInitials: string = 'U';\r\n @Input() avatarSrc: string = '';\r\n @Input() avatarIconName: string = 'remixUser3Line';\r\n \r\n // Outputs\r\n @Output() avatarClick = new EventEmitter<void>();\r\n \r\n // Internal state\r\n activeTab = signal<string>('');\r\n isDesktop = signal<boolean>(false);\r\n \r\n private mutationObserver?: MutationObserver;\r\n \r\n constructor(private elementRef: ElementRef) {}\r\n \r\n ngOnInit(): void {\r\n console.log('DsMobileTabsComponent initialized');\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial removal\r\n this.removeTitleAttributes();\r\n \r\n // Set up mutation observer to continuously remove title attributes\r\n this.setupTitleRemovalObserver();\r\n }\r\n \r\n ngOnDestroy(): void {\r\n if (this.mutationObserver) {\r\n this.mutationObserver.disconnect();\r\n }\r\n }\r\n \r\n private setupTitleRemovalObserver(): void {\r\n const config = { \r\n attributes: true, \r\n attributeFilter: ['title'],\r\n subtree: true,\r\n childList: true\r\n };\r\n \r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'attributes' && mutation.attributeName === 'title') {\r\n const target = mutation.target as HTMLElement;\r\n if (target.tagName === 'ION-TAB-BUTTON' && target.hasAttribute('title')) {\r\n target.removeAttribute('title');\r\n }\r\n }\r\n });\r\n // Also do a sweep after any changes\r\n this.removeTitleAttributes();\r\n });\r\n \r\n this.mutationObserver.observe(this.elementRef.nativeElement, config);\r\n }\r\n \r\n private removeTitleAttributes(): void {\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n tabButtons.forEach((button: HTMLElement) => {\r\n if (button.hasAttribute('title')) {\r\n button.removeAttribute('title');\r\n }\r\n // Also remove from the native button inside shadow DOM\r\n const nativeButton = button.shadowRoot?.querySelector('button');\r\n if (nativeButton?.hasAttribute('title')) {\r\n nativeButton.removeAttribute('title');\r\n }\r\n });\r\n }\r\n \r\n trackByTabId(index: number, tab: TabConfig): string {\r\n return tab.id;\r\n }\r\n \r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n \r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport type { LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxHeaderComponent\r\n * \r\n * Shared header component for all lightbox types (image, PDF, etc.)\r\n * Displays author information and close button with consistent styling.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-header',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent, DsAvatarComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n template: `\r\n @if (author()) {\r\n <div class=\"lightbox-header lightbox-context\">\r\n <div class=\"header-content\">\r\n <!-- Post author info -->\r\n <div class=\"post-author-info\">\r\n <ds-avatar\r\n [initials]=\"author()!.avatarInitials ?? ''\"\r\n [type]=\"author()!.avatarType ?? 'initials'\"\r\n [src]=\"author()!.avatarSrc ?? ''\"\r\n size=\"md\"\r\n />\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ author()!.name }}</div>\r\n <div class=\"author-meta\">\r\n @if (author()!.role) {\r\n <span>{{ author()!.role }}</span>\r\n }\r\n @if (author()!.role && author()!.timestamp) {\r\n <span class=\"separator\">·</span>\r\n }\r\n @if (author()!.timestamp) {\r\n <span>{{ author()!.timestamp }}</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"closeClick.emit()\"\r\n class=\"close-button\"\r\n [ariaLabel]=\"'Close'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n }\r\n `,\r\n styles: [`\r\n .lightbox-header {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 1000;\r\n padding: 0 16px;\r\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.4) 80%, transparent 100%);\r\n pointer-events: none;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n pointer-events: auto;\r\n }\r\n\r\n .post-author-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n .author-name {\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n }\r\n\r\n .author-meta {\r\n color: rgba(255, 255, 255, 0.7);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n\r\n .author-meta .separator {\r\n color: rgba(255, 255, 255, 0.5);\r\n }\r\n\r\n .close-button {\r\n pointer-events: auto;\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .close-button::ng-deep button {\r\n color: white !important;\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border-radius: 50%;\r\n transition: background 0.2s ease;\r\n border: none;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .close-button::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep button:active {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep svg {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Safe area support for notched devices */\r\n @supports (padding-top: env(safe-area-inset-top)) {\r\n .lightbox-header {\r\n padding-top: calc(16px + env(safe-area-inset-top));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxHeaderComponent {\r\n /**\r\n * Author information to display\r\n */\r\n author = input<LightboxAuthor>();\r\n\r\n /**\r\n * Emitted when close button is clicked\r\n */\r\n closeClick = output<void>();\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileLightboxFooterComponent\r\n * \r\n * Shared footer component for all lightbox types (image, PDF, etc.)\r\n * Displays navigation controls (for multiple images) and action buttons.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-footer',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n template: `\r\n <div class=\"lightbox-footer\">\r\n <!-- Navigation controls (only shown for multiple images) -->\r\n @if (showNavigation() && totalImages() > 1) {\r\n <div class=\"footer-navigation\">\r\n <button \r\n class=\"nav-button prev\"\r\n (click)=\"prevClick.emit()\"\r\n [disabled]=\"currentIndex() === 0\"\r\n aria-label=\"Previous image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n \r\n <div class=\"counter\">\r\n {{ currentIndex() + 1 }} / {{ totalImages() }}\r\n </div>\r\n \r\n <button \r\n class=\"nav-button next\"\r\n (click)=\"nextClick.emit()\"\r\n [disabled]=\"currentIndex() === totalImages() - 1\"\r\n aria-label=\"Next image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n \r\n <!-- Action buttons -->\r\n <div class=\"footer-actions\">\r\n <div class=\"action-buttons-left\">\r\n <!-- Like button -->\r\n <ds-icon-button\r\n [icon]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"likeClick.emit()\"\r\n [attr.data-liked]=\"isLiked()\"\r\n class=\"action-button-like\"\r\n [ariaLabel]=\"'Like'\">\r\n </ds-icon-button>\r\n \r\n <!-- Comment button -->\r\n <ds-icon-button\r\n icon=\"remixChat3Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"commentClick.emit()\"\r\n class=\"action-button-comment\"\r\n [ariaLabel]=\"'Comment'\">\r\n </ds-icon-button>\r\n </div>\r\n \r\n <ds-icon-button\r\n icon=\"remixShare2Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"shareClick.emit()\"\r\n class=\"action-button-share\"\r\n [ariaLabel]=\"'Share'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n .lightbox-footer {\r\n position: fixed;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 100;\r\n padding: 16px 20px 20px 20px;\r\n background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.6) 50%, rgba(0, 0, 0, 0.4) 75%, transparent 100%);\r\n pointer-events: none;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n\r\n /* Navigation controls */\r\n .footer-navigation {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 24px;\r\n pointer-events: auto;\r\n }\r\n\r\n .nav-button {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n border-radius: 50%;\r\n color: white;\r\n width: 40px;\r\n height: 40px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n padding: 0;\r\n }\r\n\r\n .nav-button:hover:not(:disabled) {\r\n background: rgba(255, 255, 255, 0.2);\r\n transform: scale(1.05);\r\n }\r\n\r\n .nav-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .nav-button:disabled {\r\n opacity: 0.3;\r\n cursor: not-allowed;\r\n }\r\n\r\n .nav-button svg {\r\n width: 24px;\r\n height: 24px;\r\n flex-shrink: 0;\r\n }\r\n\r\n .counter {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: 100px;\r\n padding: 8px 16px;\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 1;\r\n letter-spacing: -0.3px;\r\n pointer-events: auto;\r\n user-select: none;\r\n }\r\n\r\n .footer-actions {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 16px;\r\n pointer-events: auto;\r\n }\r\n\r\n .action-buttons-left {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n\r\n /* Style the action buttons to match the ghost/transparent look */\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button,\r\n .action-button-share::ng-deep button {\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border: 1px solid rgba(255, 255, 255, 0.2) !important;\r\n color: white !important;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n transition: all 0.2s ease;\r\n }\r\n\r\n .action-button-like::ng-deep button:hover,\r\n .action-button-comment::ng-deep button:hover,\r\n .action-button-share::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.2) !important;\r\n transform: scale(1.02);\r\n }\r\n\r\n .action-button-like::ng-deep button:active,\r\n .action-button-comment::ng-deep button:active,\r\n .action-button-share::ng-deep button:active {\r\n transform: scale(0.98);\r\n }\r\n\r\n /* Icon and label colors */\r\n .action-button-like::ng-deep button svg,\r\n .action-button-comment::ng-deep button svg,\r\n .action-button-share::ng-deep button svg,\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon,\r\n .action-button-share::ng-deep button .btn__icon,\r\n .action-button-like::ng-deep button .btn__content,\r\n .action-button-comment::ng-deep button .btn__content {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Make sure icons are visible */\r\n .action-button-like::ng-deep button .btn__icon svg,\r\n .action-button-comment::ng-deep button .btn__icon svg,\r\n .action-button-share::ng-deep button .btn__icon svg {\r\n color: white !important;\r\n fill: white !important;\r\n display: block !important;\r\n opacity: 1 !important;\r\n visibility: visible !important;\r\n width: 20px !important;\r\n height: 20px !important;\r\n }\r\n\r\n /* Ensure icon wrapper is visible */\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon,\r\n .action-button-share::ng-deep button .btn__icon {\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n flex-shrink: 0 !important;\r\n }\r\n\r\n /* Like button active state (pink heart) */\r\n .action-button-like[data-liked=\"true\"]::ng-deep button svg {\r\n fill: #f91880 !important;\r\n color: #f91880 !important;\r\n }\r\n\r\n .action-button-like[data-liked=\"true\"]::ng-deep button {\r\n border-color: rgba(249, 24, 128, 0.3) !important;\r\n }\r\n\r\n /* All action buttons should have same circular styling */\r\n .action-button-like,\r\n .action-button-comment,\r\n .action-button-share {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button,\r\n .action-button-share::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 44px !important;\r\n height: 44px !important;\r\n min-width: 44px !important;\r\n min-height: 44px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n /* Safe area support for footer */\r\n @supports (padding-bottom: env(safe-area-inset-bottom)) {\r\n .lightbox-footer {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxFooterComponent {\r\n /**\r\n * Whether to show navigation controls\r\n */\r\n showNavigation = input<boolean>(false);\r\n\r\n /**\r\n * Current image index (0-based)\r\n */\r\n currentIndex = input<number>(0);\r\n\r\n /**\r\n * Total number of images\r\n */\r\n totalImages = input<number>(1);\r\n\r\n /**\r\n * Whether the content is liked\r\n */\r\n isLiked = input<boolean>(false);\r\n\r\n /**\r\n * Number of likes\r\n */\r\n likeCount = input<number>(0);\r\n\r\n /**\r\n * Number of comments\r\n */\r\n commentCount = input<number>(0);\r\n\r\n /**\r\n * Emitted when previous button is clicked\r\n */\r\n prevClick = output<void>();\r\n\r\n /**\r\n * Emitted when next button is clicked\r\n */\r\n nextClick = output<void>();\r\n\r\n /**\r\n * Emitted when like button is clicked\r\n */\r\n likeClick = output<void>();\r\n\r\n /**\r\n * Emitted when comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n\r\n /**\r\n * Emitted when share button is clicked\r\n */\r\n shareClick = output<void>();\r\n}\r\n\r\n","import {\r\n Component,\r\n signal,\r\n computed,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n HostListener\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonSpinner,\r\n GestureController,\r\n Gesture\r\n} from '@ionic/angular/standalone';\r\nimport { Share } from '@capacitor/share';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxImage, LightboxAuthor } from './ds-mobile-lightbox.service';\r\nimport Swiper from 'swiper';\r\nimport type { SwiperOptions } from 'swiper/types';\r\n\r\n/**\r\n * DsMobileLightboxImageComponent\r\n * \r\n * Full-screen image lightbox component with Swiper.js navigation and pinch-zoom.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - Swiper.js for smooth image navigation\r\n * - Pinch to zoom in/out\r\n * - Double-tap to toggle zoom\r\n * - Swipe down to close (when not zoomed)\r\n * - Image counter and navigation controls\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openImage() {\r\n * this.lightbox.openImages({\r\n * images: [{ type: 'image', src: 'image.jpg', title: 'My Image' }]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-image',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonSpinner,\r\n DsIconButtonComponent,\r\n DsAvatarComponent,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"lightbox-overlay\" \r\n [class.zoomed]=\"isZoomed()\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and close button -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n />\r\n\r\n <!-- Swiper container -->\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n @for (image of images; track image.src; let i = $index) {\r\n <div class=\"swiper-slide\">\r\n <div class=\"image-zoom-container\" [attr.data-index]=\"i\">\r\n <img \r\n [src]=\"image.src\"\r\n [alt]=\"image.alt || 'Lightbox image'\"\r\n class=\"lightbox-image\"\r\n (load)=\"onImageLoad(i)\"\r\n (error)=\"onImageError(i)\">\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <!-- Loading indicator -->\r\n @if (isLoading()) {\r\n <div class=\"loading-spinner\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n </div>\r\n }\r\n\r\n <!-- Footer with navigation and actions -->\r\n <ds-mobile-lightbox-footer\r\n [showNavigation]=\"showControls && images.length > 1\"\r\n [currentIndex]=\"currentIndex()\"\r\n [totalImages]=\"images.length\"\r\n [isLiked]=\"isLiked()\"\r\n [likeCount]=\"likeCount()\"\r\n [commentCount]=\"commentCount()\"\r\n (prevClick)=\"previousImage()\"\r\n (nextClick)=\"nextImage()\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n </div>\r\n </div>\r\n `,\r\n styleUrl: './ds-mobile-lightbox.css'\r\n})\r\nexport class DsMobileLightboxImageComponent implements OnInit, AfterViewInit, OnDestroy {\r\n // Inputs (passed from service as regular properties, not signals)\r\n images!: LightboxImage[];\r\n author?: LightboxAuthor;\r\n initialIndex: number = 0;\r\n enableZoom: boolean = true;\r\n showControls: boolean = true;\r\n enableSwipe: boolean = true;\r\n showInfo: boolean = true;\r\n animation: 'fade' | 'zoom' | 'slide' = 'fade';\r\n onCloseRequested?: () => void;\r\n\r\n // View children\r\n @ViewChild('swiperContainer', { read: ElementRef }) swiperContainer!: ElementRef<HTMLDivElement>;\r\n\r\n // State\r\n currentIndex = signal(0);\r\n scale = signal(1);\r\n isZoomed = signal(false);\r\n isLoading = signal(true);\r\n hasError = signal(false);\r\n \r\n // Action states\r\n isLiked = signal(false);\r\n likeCount = signal(0);\r\n commentCount = signal(0);\r\n\r\n // Computed\r\n currentImage = computed(() => this.images[this.currentIndex()]);\r\n\r\n // Swiper instance\r\n private swiper?: Swiper;\r\n private zoomData: Map<number, { scale: number; x: number; y: number }> = new Map();\r\n\r\n constructor(\r\n private gestureCtrl: GestureController\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Set initial index from the passed property\r\n if (this.initialIndex !== undefined) {\r\n this.currentIndex.set(this.initialIndex);\r\n }\r\n \r\n // Initialize action states from current image\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n this.initializeZoomGestures();\r\n }, 100);\r\n }\r\n\r\n ngOnDestroy(): void {\r\n // Clean up Swiper\r\n if (this.swiper) {\r\n this.swiper.destroy();\r\n this.swiper = undefined;\r\n }\r\n }\r\n /**\r\n * Initialize Swiper for image navigation\r\n */\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) {\r\n console.error('[Lightbox] Swiper container not found');\r\n return;\r\n }\r\n\r\n const swiperOptions: SwiperOptions = {\r\n initialSlide: this.initialIndex,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n slidesPerView: 1,\r\n spaceBetween: 0,\r\n touchRatio: 1,\r\n longSwipesRatio: 0.5,\r\n threshold: 10,\r\n on: {\r\n slideChange: (swiper) => {\r\n this.currentIndex.set(swiper.activeIndex);\r\n this.updateActionStates();\r\n \r\n // Check if the image is already loaded\r\n const currentSlide = swiper.slides[swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n // Image is already loaded\r\n this.isLoading.set(false);\r\n }\r\n },\r\n slideChangeTransitionStart: () => {\r\n // Don't show loading spinner if image is already loaded\r\n const currentSlide = this.swiper?.slides[this.swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (!img || !img.complete || img.naturalHeight === 0) {\r\n this.isLoading.set(true);\r\n }\r\n }\r\n }\r\n };\r\n\r\n this.swiper = new Swiper(this.swiperContainer.nativeElement, swiperOptions);\r\n \r\n // Check if the initial image is already loaded\r\n setTimeout(() => {\r\n const currentSlide = this.swiper?.slides[this.currentIndex()];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n this.isLoading.set(false);\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * Initialize pinch-zoom gestures for all slides\r\n */\r\n private initializeZoomGestures(): void {\r\n if (!this.enableZoom) return;\r\n\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.image-zoom-container');\r\n \r\n slides.forEach((slide, index) => {\r\n this.initializeZoomForSlide(slide as HTMLElement, index);\r\n });\r\n }\r\n\r\n /**\r\n * Initialize zoom gestures for a specific slide\r\n */\r\n private initializeZoomForSlide(container: HTMLElement, index: number): void {\r\n let initialDistance = 0;\r\n let initialScale = 1;\r\n let currentScale = 1;\r\n let lastTap = 0;\r\n\r\n // Double-tap to zoom\r\n container.addEventListener('click', (event: MouseEvent) => {\r\n const now = Date.now();\r\n const timeSinceLastTap = now - lastTap;\r\n\r\n if (timeSinceLastTap < 300 && timeSinceLastTap > 0) {\r\n event.preventDefault();\r\n this.toggleZoom(container, index);\r\n }\r\n\r\n lastTap = now;\r\n });\r\n\r\n // Pinch to zoom\r\n const getTouchDistance = (touches: TouchList) => {\r\n const dx = touches[0].clientX - touches[1].clientX;\r\n const dy = touches[0].clientY - touches[1].clientY;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n };\r\n\r\n container.addEventListener('touchstart', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n initialDistance = getTouchDistance(event.touches);\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n initialScale = zoomData.scale;\r\n \r\n // Disable Swiper when zooming\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchmove', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n \r\n const currentDistance = getTouchDistance(event.touches);\r\n const pinchScale = currentDistance / initialDistance;\r\n \r\n currentScale = Math.max(1, Math.min(initialScale * pinchScale, 4));\r\n \r\n const img = container.querySelector('img');\r\n if (img) {\r\n img.style.transform = `scale(${currentScale})`;\r\n }\r\n \r\n if (currentScale > 1) {\r\n this.isZoomed.set(true);\r\n } else {\r\n this.isZoomed.set(false);\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchend', (event: TouchEvent) => {\r\n if (event.touches.length < 2) {\r\n // Save zoom state\r\n this.zoomData.set(index, { scale: currentScale, x: 0, y: 0 });\r\n \r\n // Re-enable Swiper if not zoomed\r\n if (this.swiper && currentScale <= 1) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Toggle zoom on double-tap\r\n */\r\n private toggleZoom(container: HTMLElement, index: number): void {\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n const img = container.querySelector('img');\r\n \r\n if (!img) return;\r\n\r\n if (zoomData.scale > 1) {\r\n // Zoom out\r\n img.style.transform = 'scale(1)';\r\n this.zoomData.set(index, { scale: 1, x: 0, y: 0 });\r\n this.isZoomed.set(false);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n } else {\r\n // Zoom in\r\n img.style.transform = 'scale(2)';\r\n this.zoomData.set(index, { scale: 2, x: 0, y: 0 });\r\n this.isZoomed.set(true);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Update action states (like, comments) when slide changes\r\n */\r\n private updateActionStates(): void {\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n /**\r\n * Close the lightbox\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle share button click\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[Lightbox] Share button clicked');\r\n const currentImg = this.currentImage();\r\n \r\n try {\r\n await Share.share({\r\n title: currentImg.title || 'Shared Image',\r\n url: currentImg.src,\r\n dialogTitle: 'Share Image',\r\n });\r\n } catch (error) {\r\n console.error('[Lightbox] Share failed:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Handle like button toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[Lightbox] Like button toggled');\r\n this.isLiked.update(liked => !liked);\r\n \r\n if (this.isLiked()) {\r\n this.likeCount.update(count => count + 1);\r\n } else {\r\n this.likeCount.update(count => Math.max(0, count - 1));\r\n }\r\n }\r\n\r\n /**\r\n * Handle reply/comment button click\r\n */\r\n onReply(): void {\r\n console.log('[Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the next image\r\n */\r\n nextImage(): void {\r\n if (this.swiper && this.currentIndex() < this.images.length - 1) {\r\n this.swiper.slideNext();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the previous image\r\n */\r\n previousImage(): void {\r\n if (this.swiper && this.currentIndex() > 0) {\r\n this.swiper.slidePrev();\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load success\r\n */\r\n onImageLoad(index: number): void {\r\n if (index === this.currentIndex()) {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load error\r\n */\r\n onImageError(index: number): void {\r\n if (index === this.currentIndex()) {\r\n console.error(`[Lightbox] Image ${index} failed to load`);\r\n this.isLoading.set(false);\r\n this.hasError.set(true);\r\n }\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonContent,\r\n IonSpinner\r\n} from '@ionic/angular/standalone';\r\nimport { Filesystem, Directory } from '@capacitor/filesystem';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Share } from '@capacitor/share';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxPdf, LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxPdfComponent\r\n * \r\n * PDF viewer component that displays PDF info and allows users to open PDFs in the native device viewer.\r\n * Shows a lightbox with PDF details first, then user can choose to open in native viewer.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - PDF info preview (title, size, icon)\r\n * - User-initiated native PDF viewing (iOS/Android)\r\n * - Download and cache support\r\n * - Share functionality\r\n * - Loading states\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openPdf() {\r\n * this.lightbox.openPdf({\r\n * pdf: { type: 'pdf', src: 'document.pdf', title: 'My Document' }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-pdf',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonContent,\r\n IonSpinner,\r\n DsAvatarComponent,\r\n DsButtonComponent,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content \r\n [fullscreen]=\"true\"\r\n class=\"lightbox-content pdf-viewer\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and close button -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n />\r\n\r\n <!-- PDF Info & Actions -->\r\n <div class=\"pdf-container\">\r\n @if (isLoading) {\r\n <div class=\"loading-state\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n <p>Loading PDF...</p>\r\n </div>\r\n } @else if (hasError) {\r\n <div class=\"error-state\">\r\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M12 8V12M12 16H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n <h3>Failed to Load PDF</h3>\r\n <p>{{ errorMessage }}</p>\r\n <button class=\"retry-button\" (click)=\"openPdfInNativeViewer()\">\r\n Try Again\r\n </button>\r\n </div>\r\n } @else {\r\n <div class=\"pdf-content\">\r\n <!-- PDF Icon -->\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"xl\"\r\n />\r\n \r\n <!-- PDF Title (same as attachment fileName) -->\r\n <h2 class=\"pdf-title\">{{ getDisplayTitle() }}</h2>\r\n \r\n <!-- PDF Metadata (same format as attachment: PDF · fileSize) -->\r\n <div class=\"pdf-meta\">\r\n PDF · {{ pdf.fileSize ? formatFileSize(pdf.fileSize) : '' }}\r\n </div>\r\n \r\n <!-- Open Button -->\r\n <ds-button\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (clicked)=\"openPdfInNativeViewer()\"\r\n class=\"open-pdf-button\">\r\n Open Preview\r\n </ds-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Bottom actions -->\r\n <ds-mobile-lightbox-footer\r\n [isLiked]=\"false\"\r\n [likeCount]=\"0\"\r\n [commentCount]=\"0\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n </div>\r\n </ion-content>\r\n `,\r\n styleUrl: './ds-mobile-lightbox-pdf.css'\r\n})\r\nexport class DsMobileLightboxPdfComponent implements OnInit {\r\n // Inputs (passed from service as regular properties)\r\n pdf!: LightboxPdf;\r\n author?: LightboxAuthor;\r\n onCloseRequested?: () => void;\r\n\r\n // State\r\n isLoading = false;\r\n hasError = false;\r\n errorMessage = '';\r\n cachedFilePath?: string;\r\n\r\n constructor() {}\r\n\r\n ngOnInit(): void {\r\n console.log('[PDF Lightbox] Initializing with PDF:', this.pdf);\r\n \r\n // Don't automatically open - let user click the \"Open\" button\r\n // this.openPdfInNativeViewer();\r\n }\r\n\r\n /**\r\n * Open the PDF in the native device viewer\r\n */\r\n async openPdfInNativeViewer(): Promise<void> {\r\n if (!this.pdf?.src) {\r\n console.error('[PDF Lightbox] No PDF source provided');\r\n this.hasError = true;\r\n this.errorMessage = 'No PDF file provided';\r\n return;\r\n }\r\n\r\n this.isLoading = true;\r\n this.hasError = false;\r\n this.errorMessage = '';\r\n\r\n try {\r\n console.log('[PDF Lightbox] Opening PDF:', this.pdf.src);\r\n \r\n // Check if it's already a full URL\r\n let pdfUrl: string;\r\n \r\n if (this.pdf.src.startsWith('http://') || this.pdf.src.startsWith('https://')) {\r\n // Already a full URL\r\n pdfUrl = this.pdf.src;\r\n } else {\r\n // Relative path - construct full URL\r\n // Use current origin (which includes the dev server URL in Capacitor)\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n pdfUrl = `${window.location.origin}/${cleanPath}`;\r\n }\r\n \r\n console.log('[PDF Lightbox] Opening PDF at URL:', pdfUrl);\r\n \r\n // Use Browser to open the PDF\r\n await Browser.open({ \r\n url: pdfUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n this.isLoading = false;\r\n \r\n // Close the modal after opening browser\r\n setTimeout(() => {\r\n this.close();\r\n }, 500);\r\n } catch (error: any) {\r\n console.error('[PDF Lightbox] Error opening PDF:', error);\r\n this.isLoading = false;\r\n this.hasError = true;\r\n this.errorMessage = error?.message || 'Failed to open PDF';\r\n }\r\n }\r\n\r\n /**\r\n * Download a remote PDF and open it\r\n */\r\n private async downloadAndOpenPdf(): Promise<void> {\r\n try {\r\n console.log('[PDF Lightbox] Downloading PDF from:', this.pdf.src);\r\n \r\n // Fetch the PDF\r\n const response = await fetch(this.pdf.src);\r\n if (!response.ok) {\r\n throw new Error(`Failed to download PDF: ${response.statusText}`);\r\n }\r\n \r\n const blob = await response.blob();\r\n const base64Data = await this.blobToBase64(blob);\r\n \r\n // Generate a filename\r\n const fileName = this.pdf.title \r\n ? `${this.pdf.title.replace(/[^a-z0-9]/gi, '_')}.pdf`\r\n : 'document.pdf';\r\n \r\n // Save to cache directory\r\n const result = await Filesystem.writeFile({\r\n path: fileName,\r\n data: base64Data,\r\n directory: Directory.Cache\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF saved to cache:', result.uri);\r\n this.cachedFilePath = result.uri;\r\n \r\n // Open using Browser\r\n await Browser.open({ \r\n url: result.uri,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error downloading/opening PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Open a local PDF file\r\n */\r\n private async openLocalPdf(): Promise<void> {\r\n try {\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n const fullUrl = window.location.origin + '/' + cleanPath;\r\n \r\n await Browser.open({ \r\n url: fullUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] Local PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error opening local PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Convert Blob to base64 string\r\n */\r\n private blobToBase64(blob: Blob): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onloadend = () => {\r\n const base64String = reader.result as string;\r\n // Remove the data URL prefix\r\n const base64Data = base64String.split(',')[1];\r\n resolve(base64Data);\r\n };\r\n reader.onerror = reject;\r\n reader.readAsDataURL(blob);\r\n });\r\n }\r\n\r\n /**\r\n * Get display title with file extension\r\n * If title is provided, ensure it has .pdf extension\r\n * Otherwise, extract filename from src\r\n */\r\n getDisplayTitle(): string {\r\n if (this.pdf.title) {\r\n // If title doesn't end with .pdf, add it\r\n return this.pdf.title.endsWith('.pdf') ? this.pdf.title : `${this.pdf.title}.pdf`;\r\n }\r\n \r\n // Extract filename from src\r\n if (this.pdf.src) {\r\n const filename = this.pdf.src.split('/').pop() || 'PDF Document.pdf';\r\n return filename;\r\n }\r\n \r\n return 'PDF Document.pdf';\r\n }\r\n\r\n /**\r\n * Format file size for display\r\n */\r\n formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 Bytes';\r\n \r\n const k = 1024;\r\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n \r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n }\r\n\r\n /**\r\n * Share the PDF\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[PDF Lightbox] Share button clicked');\r\n \r\n if (!this.pdf?.src) return;\r\n \r\n try {\r\n await Share.share({\r\n title: this.pdf.title || 'PDF Document',\r\n text: this.pdf.description || '',\r\n url: this.pdf.src,\r\n dialogTitle: 'Share PDF'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF shared successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error sharing PDF:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Close the PDF viewer\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle like toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[PDF Lightbox] Like toggled');\r\n // TODO: Implement like logic for PDFs if needed\r\n }\r\n\r\n /**\r\n * Handle reply/comment\r\n * Close the lightbox and signal to open post detail with comment focus\r\n */\r\n onReply(): void {\r\n console.log('[PDF Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n // The calling code should handle opening the post detail modal\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable, ApplicationRef, ComponentRef, createComponent, EnvironmentInjector, Injector } from '@angular/core';\r\nimport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nimport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\n\r\n/**\r\n * Media file types supported by the lightbox\r\n */\r\nexport type LightboxMediaType = 'image' | 'pdf';\r\n\r\n/**\r\n * Base media file interface\r\n */\r\nexport interface LightboxMediaFile {\r\n /** File source URL */\r\n src: string;\r\n /** Media type - determines which viewer to use */\r\n type: LightboxMediaType;\r\n /** File title */\r\n title?: string;\r\n /** File description */\r\n description?: string;\r\n}\r\n\r\n/**\r\n * Image data for lightbox display\r\n */\r\nexport interface LightboxImage extends LightboxMediaFile {\r\n type: 'image';\r\n /** Alt text for accessibility */\r\n alt?: string;\r\n /** Thumbnail URL for faster loading (optional) */\r\n thumbnail?: string;\r\n /** Whether the image is liked */\r\n isLiked?: boolean;\r\n /** Number of likes */\r\n likeCount?: number;\r\n /** Number of comments */\r\n commentCount?: number;\r\n}\r\n\r\n/**\r\n * PDF document data for lightbox display\r\n */\r\nexport interface LightboxPdf extends LightboxMediaFile {\r\n type: 'pdf';\r\n /** File size in bytes (optional, for display) */\r\n fileSize?: number;\r\n /** Number of pages (optional, for display) */\r\n pageCount?: number;\r\n}\r\n\r\n/**\r\n * Author metadata for the lightbox\r\n */\r\nexport interface LightboxAuthor {\r\n /** Author name */\r\n name: string;\r\n /** Author role/subtitle */\r\n role?: string;\r\n /** Author avatar URL */\r\n avatarSrc?: string;\r\n /** Author avatar initials (if no photo) */\r\n avatarInitials?: string;\r\n /** Avatar type */\r\n avatarType?: 'photo' | 'initials';\r\n /** Timestamp */\r\n timestamp?: string;\r\n}\r\n\r\n/**\r\n * Configuration options for image lightbox\r\n */\r\nexport interface LightboxImageOptions {\r\n /** Array of images to display */\r\n images: LightboxImage[];\r\n /** Author information to display in header */\r\n author?: LightboxAuthor;\r\n /** Initial image index to show (0-based) */\r\n initialIndex?: number;\r\n /** Enable pinch-to-zoom and double-tap zoom */\r\n enableZoom?: boolean;\r\n /** Show navigation controls (arrows, counter) */\r\n showControls?: boolean;\r\n /** Enable swipe gestures to navigate between images */\r\n enableSwipe?: boolean;\r\n /** Show image info (title, description) */\r\n showInfo?: boolean;\r\n /** Animation type for opening */\r\n animation?: 'fade' | 'zoom' | 'slide';\r\n}\r\n\r\n/**\r\n * Configuration options for PDF lightbox\r\n */\r\nexport interface LightboxPdfOptions {\r\n /** PDF document to display */\r\n pdf: LightboxPdf;\r\n /** Author information to display */\r\n author?: LightboxAuthor;\r\n}\r\n\r\n/**\r\n * Generic lightbox options (for backward compatibility)\r\n */\r\nexport type LightboxOptions = LightboxImageOptions;\r\n\r\n/**\r\n * DsMobileLightboxService\r\n * \r\n * Service for displaying media files (images and PDFs) in full-screen viewers.\r\n * - Images: Full-screen modal with gestures (pinch-zoom, swipe navigation)\r\n * - PDFs: Native device PDF viewer (iOS/Android)\r\n * \r\n * Features:\r\n * - Full-screen image viewing with gestures\r\n * - Native PDF viewing\r\n * - Swipe navigation between images\r\n * - Pinch-to-zoom and double-tap zoom for images\r\n * - Mobile-optimized touch gestures\r\n * - Share functionality\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * // Open images\r\n * async openImages() {\r\n * const modal = await this.lightbox.openImages({\r\n * images: [\r\n * {\r\n * type: 'image',\r\n * src: 'https://example.com/image1.jpg',\r\n * title: 'Beautiful Sunset'\r\n * }\r\n * ]\r\n * });\r\n * \r\n * // Listen for when lightbox is dismissed\r\n * const { data } = await modal.onDidDismiss();\r\n * if (data?.action === 'comment') {\r\n * // Open post detail modal with comment focus\r\n * this.openPostDetail({ focusComment: true });\r\n * }\r\n * }\r\n * \r\n * // Open PDF\r\n * async openPdf() {\r\n * await this.lightbox.openPdf({\r\n * pdf: {\r\n * type: 'pdf',\r\n * src: 'https://example.com/document.pdf',\r\n * title: 'Document'\r\n * }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileLightboxService {\r\n private currentLightbox: ComponentRef<any> | null = null;\r\n\r\n constructor(\r\n private appRef: ApplicationRef,\r\n private injector: EnvironmentInjector\r\n ) {}\r\n\r\n /**\r\n * Open the lightbox with images (backward compatible method)\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async open(options: LightboxOptions): Promise<() => void> {\r\n return this.openImages(options);\r\n }\r\n\r\n /**\r\n * Open the image lightbox with one or more images\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openImages(options: LightboxImageOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening images with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxImageComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.images = options.images;\r\n componentRef.instance.author = options.author;\r\n componentRef.instance.initialIndex = options.initialIndex ?? 0;\r\n componentRef.instance.enableZoom = options.enableZoom !== false;\r\n componentRef.instance.showControls = options.showControls !== false;\r\n componentRef.instance.enableSwipe = options.enableSwipe !== false;\r\n componentRef.instance.showInfo = options.showInfo !== false;\r\n componentRef.instance.animation = options.animation ?? 'fade';\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] Image lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Open the PDF lightbox (opens native PDF viewer)\r\n * \r\n * @param options Configuration options for the PDF lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openPdf(options: LightboxPdfOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening PDF with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxPdfComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.pdf = options.pdf;\r\n componentRef.instance.author = options.author;\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] PDF lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Close the currently open lightbox\r\n */\r\n close(): void {\r\n if (this.currentLightbox) {\r\n const domElem = (this.currentLightbox.hostView as any).rootNodes[0] as HTMLElement;\r\n domElem.remove();\r\n this.appRef.detachView(this.currentLightbox.hostView);\r\n this.currentLightbox.destroy();\r\n this.currentLightbox = null;\r\n }\r\n }\r\n\r\n /**\r\n * Check if a lightbox is currently open\r\n */\r\n isOpen(): boolean {\r\n return this.currentLightbox !== null;\r\n }\r\n}\r\n\r\n","// Components\r\nexport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nexport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\nexport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nexport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\n\r\n// Service and Types\r\nexport { \r\n DsMobileLightboxService,\r\n type LightboxImage,\r\n type LightboxPdf,\r\n type LightboxMediaFile,\r\n type LightboxMediaType,\r\n type LightboxAuthor,\r\n type LightboxOptions,\r\n type LightboxImageOptions,\r\n type LightboxPdfOptions\r\n} from './ds-mobile-lightbox.service';\r\n\r\n// Legacy export for backward compatibility\r\nexport { DsMobileLightboxImageComponent as DsMobileLightboxComponent } from './ds-mobile-lightbox-image';\r\n\r\n","import { Component, Input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsMobileLightboxService, LightboxImage } from '../lightbox/ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileInlinePhotoComponent\r\n * \r\n * Displays one or multiple photos in a grid layout optimized for social feeds.\r\n * Supports up to 5 visible images with automatic grid layouts.\r\n * \r\n * Features:\r\n * - Automatic grid layouts for 1-5 images\r\n * - Shows \"+N more\" overlay if more than 5 images\r\n * - Opens lightbox with all images (including hidden ones) when clicked\r\n * - Optimized layouts: 1 full, 2 split, 3 masonry, 4 grid, 5 grid\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-inline-photo\r\n * [images]=\"['img1.jpg', 'img2.jpg', 'img3.jpg']\"\r\n * [author]=\"authorInfo\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-inline-photo',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div \r\n class=\"photo-grid\" \r\n [attr.data-count]=\"visibleImages.length\"\r\n [class.has-more]=\"hiddenCount > 0\">\r\n @for (image of visibleImages; track image; let i = $index) {\r\n <div \r\n class=\"photo-item\"\r\n [class.last]=\"i === visibleImages.length - 1\"\r\n (click)=\"openLightbox(i, $event)\">\r\n <img \r\n [src]=\"image\" \r\n [alt]=\"'Photo ' + (i + 1)\"\r\n loading=\"lazy\">\r\n \r\n <!-- Show \"+N more\" overlay on last image if there are hidden images -->\r\n @if (i === visibleImages.length - 1 && hiddenCount > 0) {\r\n <div class=\"more-overlay\">\r\n <span class=\"more-text\">+{{ hiddenCount }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n\r\n .photo-grid {\r\n display: grid;\r\n gap: 4px;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n background: var(--ds-color-neutral-100);\r\n width: 100%;\r\n }\r\n\r\n .photo-item {\r\n position: relative;\r\n overflow: hidden;\r\n cursor: pointer;\r\n background: var(--ds-color-neutral-200);\r\n aspect-ratio: 1;\r\n }\r\n\r\n .photo-item img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n display: block;\r\n transition: transform 0.2s ease;\r\n }\r\n\r\n .photo-item:active img {\r\n transform: scale(0.98);\r\n }\r\n\r\n .more-overlay {\r\n position: absolute;\r\n inset: 0;\r\n background: rgba(0, 0, 0, 0.6);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n pointer-events: none;\r\n }\r\n\r\n .more-text {\r\n color: white;\r\n font-size: 32px;\r\n font-weight: 600;\r\n font-family: var(--ds-font-family-medium);\r\n }\r\n\r\n /* 1 image: full width, 4:3 ratio */\r\n .photo-grid[data-count=\"1\"] {\r\n grid-template-columns: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"1\"] .photo-item {\r\n aspect-ratio: 4/3;\r\n }\r\n\r\n /* 2 images: side by side */\r\n .photo-grid[data-count=\"2\"] {\r\n grid-template-columns: 1fr 1fr;\r\n }\r\n\r\n /* 3 images: 1 large left, 2 stacked right */\r\n .photo-grid[data-count=\"3\"] {\r\n grid-template-columns: 2fr 1fr;\r\n grid-auto-rows: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"3\"] .photo-item:first-child {\r\n grid-row: 1 / 3;\r\n aspect-ratio: auto;\r\n }\r\n \r\n /* Right side images remain 1:1 squares */\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(2),\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(3) {\r\n aspect-ratio: 1;\r\n }\r\n\r\n /* 4 images: 2x2 grid */\r\n .photo-grid[data-count=\"4\"] {\r\n grid-template-columns: 1fr 1fr;\r\n grid-template-rows: 1fr 1fr;\r\n }\r\n\r\n /* 5 images: 2 on top, 3 on bottom */\r\n .photo-grid[data-count=\"5\"] {\r\n grid-template-columns: repeat(6, 1fr);\r\n grid-template-rows: auto auto;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item {\r\n aspect-ratio: 1;\r\n width: 100%;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(1) {\r\n grid-column: 1 / 4;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(2) {\r\n grid-column: 4 / 7;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n grid-column: 1 / 3;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(4) {\r\n grid-column: 3 / 5;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n grid-column: 5 / 7;\r\n grid-row: 2;\r\n }\r\n\r\n /* Round bottom corners for 5-image layout */\r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n border-bottom-left-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n border-bottom-right-radius: 8px;\r\n overflow: hidden;\r\n }\r\n `]\r\n})\r\nexport class DsMobileInlinePhotoComponent {\r\n /**\r\n * Array of image URLs to display\r\n */\r\n @Input() images: string[] = [];\r\n\r\n /**\r\n * Author information (passed to lightbox)\r\n */\r\n @Input() author?: {\r\n name: string;\r\n role?: string;\r\n avatarSrc?: string;\r\n avatarInitials?: string;\r\n avatarType?: 'photo' | 'initials';\r\n timestamp?: string;\r\n };\r\n\r\n /**\r\n * Maximum number of images to show inline (default: 5)\r\n * Remaining images shown in lightbox only\r\n */\r\n @Input() maxVisible: number = 5;\r\n\r\n /**\r\n * Event emitted when lightbox is opened\r\n */\r\n photoClick = output<{ index: number; totalImages: number }>();\r\n\r\n constructor(private lightboxService: DsMobileLightboxService) {}\r\n\r\n /**\r\n * Get the first N images to display inline\r\n */\r\n get visibleImages(): string[] {\r\n return this.images.slice(0, this.maxVisible);\r\n }\r\n\r\n /**\r\n * Calculate how many images are hidden\r\n */\r\n get hiddenCount(): number {\r\n return Math.max(0, this.images.length - this.maxVisible);\r\n }\r\n\r\n /**\r\n * Open lightbox with all images, starting at the clicked index\r\n */\r\n openLightbox(index: number, event?: Event): void {\r\n // Stop event propagation to prevent triggering parent click handlers\r\n if (event) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n }\r\n\r\n // Emit event\r\n this.photoClick.emit({\r\n index,\r\n totalImages: this.images.length\r\n });\r\n\r\n // Convert image URLs to LightboxImage format\r\n const lightboxImages: LightboxImage[] = this.images.map((src, i) => ({\r\n type: 'image',\r\n src,\r\n alt: `Photo ${i + 1}`\r\n }));\r\n\r\n // Open lightbox with all images (not just visible ones)\r\n this.lightboxService.openImages({\r\n images: lightboxImages,\r\n initialIndex: index,\r\n author: this.author,\r\n enableZoom: true,\r\n showControls: true,\r\n enableSwipe: true\r\n });\r\n }\r\n}\r\n\r\n","import { Injectable, Type } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Configuration options for modal presentation\r\n */\r\nexport interface ModalOptions<T = any> {\r\n /** The component to display in the modal */\r\n component: Type<T>;\r\n /** Props to pass to the component */\r\n componentProps?: Record<string, any>;\r\n /** CSS class(es) to apply to the modal */\r\n cssClass?: string | string[];\r\n /** Modal presentation style */\r\n presentationStyle?: 'fullscreen' | 'card' | 'sheet';\r\n /** Enable backdrop dismiss (tap outside to close) */\r\n backdropDismiss?: boolean;\r\n /** Show backdrop */\r\n showBackdrop?: boolean;\r\n /** Enable keyboard close (ESC key) */\r\n keyboardClose?: boolean;\r\n /** Enable swipe to close */\r\n swipeToClose?: boolean;\r\n /** Initial breakpoint (0-1) for sheet presentation */\r\n initialBreakpoint?: number;\r\n /** Available breakpoints for sheet presentation */\r\n breakpoints?: number[];\r\n /** Animation type */\r\n animated?: boolean;\r\n /** Mode (ios or md) */\r\n mode?: 'ios' | 'md';\r\n /** Whether to handle navigation back button */\r\n handleNavigationBack?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileModalService\r\n * \r\n * Generic service for displaying any component as a modal.\r\n * Built on Ionic's modal system with customizable presentation styles.\r\n * \r\n * Features:\r\n * - Open any component as a modal\r\n * - Fullscreen, card, or sheet presentation styles\r\n * - Customizable backdrop and dismissal behavior\r\n * - Native gestures and animations\r\n * - Type-safe component props\r\n * \r\n * @example\r\n * ```typescript\r\n * import { MobilePostDetailPageComponent } from './post-detail.page';\r\n * \r\n * constructor(private modal: DsMobileModalService) {}\r\n * \r\n * async openPostModal() {\r\n * await this.modal.open({\r\n * component: MobilePostDetailPageComponent,\r\n * componentProps: {\r\n * postId: '123',\r\n * authorName: 'John Doe'\r\n * },\r\n * presentationStyle: 'card',\r\n * backdropDismiss: true\r\n * });\r\n * }\r\n * ```\r\n * \r\n * @example Sheet presentation with breakpoints\r\n * ```typescript\r\n * async openSheet() {\r\n * await this.modal.open({\r\n * component: CommentsComponent,\r\n * presentationStyle: 'sheet',\r\n * initialBreakpoint: 0.5,\r\n * breakpoints: [0, 0.5, 0.75, 1],\r\n * swipeToClose: true\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open a component as a modal\r\n * \r\n * @param options Configuration options for the modal\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.open({\r\n * component: MyComponent,\r\n * componentProps: { data: 'value' },\r\n * presentationStyle: 'fullscreen'\r\n * });\r\n * ```\r\n */\r\n async open<T = any>(options: ModalOptions<T>): Promise<HTMLIonModalElement> {\r\n console.log('[Modal] Opening modal with options:', options);\r\n \r\n const {\r\n component,\r\n componentProps,\r\n cssClass,\r\n presentationStyle = 'card',\r\n backdropDismiss = true,\r\n showBackdrop = true,\r\n keyboardClose = true,\r\n swipeToClose,\r\n initialBreakpoint,\r\n breakpoints,\r\n animated = true,\r\n mode = 'ios',\r\n handleNavigationBack = true\r\n } = options;\r\n\r\n // Build modal configuration\r\n const modalConfig: any = {\r\n component,\r\n componentProps: componentProps || {},\r\n cssClass: this.buildCssClasses(cssClass, presentationStyle),\r\n mode,\r\n backdropDismiss,\r\n showBackdrop,\r\n animated,\r\n keyboardClose,\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n handle: presentationStyle === 'sheet', // Show handle for sheet presentation\r\n };\r\n\r\n // Add swipe to close for sheet presentation\r\n if (swipeToClose !== undefined) {\r\n modalConfig.canDismiss = swipeToClose;\r\n }\r\n\r\n // Add breakpoints for sheet presentation\r\n if (presentationStyle === 'sheet' && breakpoints) {\r\n modalConfig.breakpoints = breakpoints;\r\n if (initialBreakpoint !== undefined) {\r\n modalConfig.initialBreakpoint = initialBreakpoint;\r\n }\r\n }\r\n\r\n // Handle navigation back button\r\n if (handleNavigationBack) {\r\n modalConfig.canDismiss = async () => {\r\n // You can add custom logic here if needed\r\n return true;\r\n };\r\n }\r\n\r\n const modal = await this.modalController.create(modalConfig);\r\n\r\n console.log('[Modal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[Modal] Modal presented');\r\n\r\n return modal;\r\n }\r\n\r\n /**\r\n * Open a component as a fullscreen modal\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openFullscreen(PostDetailPage, { postId: '123' });\r\n * ```\r\n */\r\n async openFullscreen<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'fullscreen',\r\n backdropDismiss: false,\r\n showBackdrop: false\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a card modal\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openCard(DetailComponent, { itemId: '456' });\r\n * ```\r\n */\r\n async openCard<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'card',\r\n backdropDismiss: true,\r\n showBackdrop: true\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a bottom sheet\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @param options Additional sheet options (breakpoints, etc.)\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openSheet(\r\n * CommentsComponent,\r\n * { postId: '789' },\r\n * { initialBreakpoint: 0.5, breakpoints: [0, 0.5, 1] }\r\n * );\r\n * ```\r\n */\r\n async openSheet<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>,\r\n options?: {\r\n initialBreakpoint?: number;\r\n breakpoints?: number[];\r\n swipeToClose?: boolean;\r\n }\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'sheet',\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n swipeToClose: options?.swipeToClose ?? true,\r\n initialBreakpoint: options?.initialBreakpoint ?? 0.5,\r\n breakpoints: options?.breakpoints ?? [0, 0.5, 0.75, 1]\r\n });\r\n }\r\n\r\n /**\r\n * Close the currently open modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @param role Optional role (e.g., 'cancel', 'confirm')\r\n * @returns Promise that resolves when the modal is dismissed\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.dismiss({ saved: true }, 'confirm');\r\n * ```\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n * \r\n * @example\r\n * ```typescript\r\n * const topModal = await this.modal.getTop();\r\n * if (topModal) {\r\n * await topModal.dismiss();\r\n * }\r\n * ```\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n\r\n /**\r\n * Get all currently open modals\r\n * \r\n * @returns Promise that resolves to an array of modal elements\r\n */\r\n async getAll(): Promise<HTMLIonModalElement[]> {\r\n const modals: HTMLIonModalElement[] = [];\r\n let modal = await this.modalController.getTop();\r\n \r\n while (modal) {\r\n modals.push(modal);\r\n // Get the next modal in the stack\r\n await modal.dismiss();\r\n modal = await this.modalController.getTop();\r\n }\r\n \r\n return modals;\r\n }\r\n\r\n /**\r\n * Build CSS classes for the modal\r\n */\r\n private buildCssClasses(\r\n customClass?: string | string[],\r\n presentationStyle?: string\r\n ): string[] {\r\n const classes: string[] = ['ds-mobile-modal'];\r\n \r\n if (presentationStyle) {\r\n classes.push(`ds-modal-${presentationStyle}`);\r\n }\r\n \r\n if (customClass) {\r\n if (Array.isArray(customClass)) {\r\n classes.push(...customClass);\r\n } else {\r\n classes.push(customClass);\r\n }\r\n }\r\n \r\n return classes;\r\n }\r\n}\r\n\r\n","/**\r\n * Mobile Modal Module\r\n * \r\n * Generic service for opening any component as a modal\r\n */\r\n\r\nexport * from './ds-mobile-modal.service';\r\n\r\n","import {\r\n Component,\r\n signal,\r\n computed,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n Input,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport {\r\n IonContent,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport {\r\n DsMobilePostCardComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../post-card/ds-mobile-post-card';\r\nimport { DsMobileCommentComponent } from '../comment/ds-mobile-comment';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../lightbox';\r\nimport { \r\n DsMobileBottomSheetService, \r\n DsMobileCommentActionsBottomSheetComponent,\r\n CommentActionResult \r\n} from '../bottom-sheet';\r\n\r\n/**\r\n * Post data interface for the modal\r\n */\r\nexport interface PostDetailData {\r\n postId: string;\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarInitials?: string;\r\n avatarType?: 'photo' | 'initials';\r\n avatarSrc?: string;\r\n content: string;\r\n imageSrc?: string;\r\n imageAlt?: string;\r\n isLiked?: boolean;\r\n likeCount?: number;\r\n commentCount?: number;\r\n comments?: CommentData[];\r\n focusComment?: boolean; // Auto-focus comment input when modal opens\r\n}\r\n\r\nexport interface CommentData {\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarInitials: string;\r\n content: string;\r\n isLiked?: boolean;\r\n likeCount?: number;\r\n isOwnComment?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobilePostDetailModalComponent\r\n * \r\n * Modal wrapper for displaying post details with comments.\r\n * Follows the same pattern as the lightbox modal for consistent behavior.\r\n * \r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Image lightbox integration\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n * \r\n * This component is typically not used directly - use DsMobilePostDetailModalService instead.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n * \r\n * openPost() {\r\n * this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * content: 'Post content...'\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n DsIconButtonComponent,\r\n DsIconComponent,\r\n DsAvatarComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCommentComponent\r\n ],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content [fullscreen]=\"true\" [scrollY]=\"true\" class=\"post-modal-content\">\r\n <div class=\"post-modal-wrapper\">\r\n <!-- Header with post author info -->\r\n <div class=\"post-modal-header\">\r\n <div class=\"header-content\">\r\n <!-- Post author info -->\r\n <div class=\"post-author-info\">\r\n <ds-avatar\r\n [initials]=\"post().avatarInitials || ''\"\r\n [type]=\"post().avatarType || 'initials'\"\r\n [src]=\"post().avatarSrc || ''\"\r\n size=\"md\"\r\n />\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ post().authorName }}</div>\r\n <div class=\"author-meta\">\r\n <span>{{ post().authorRole }}</span>\r\n <span class=\"separator\">·</span>\r\n <span>{{ post().timestamp }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Luk opslag\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n\r\n <!-- Post content -->\r\n <div class=\"post-detail-container\">\r\n <!-- Post Section -->\r\n <div class=\"post-section\">\r\n <div class=\"post-content-only\">\r\n <post-text>{{ post().content }}</post-text>\r\n @if (post().imageSrc) {\r\n <post-media>\r\n <img \r\n [src]=\"post().imageSrc\"\r\n [alt]=\"post().imageAlt || 'Post image'\"\r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox()\"\r\n />\r\n </post-media>\r\n }\r\n </div>\r\n \r\n <!-- Post actions -->\r\n <div class=\"post-actions\">\r\n <action-like \r\n [active]=\"post().isLiked || false\" \r\n [count]=\"post().likeCount || 0\" />\r\n <action-comment \r\n [count]=\"post().commentCount || 0\"\r\n (commentClick)=\"focusCommentInput()\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Comments Section -->\r\n <div class=\"comments-section\">\r\n @if (post().comments && post().comments!.length > 0) {\r\n <h2 class=\"comments-header\">{{ post().comments!.length }} {{ post().comments!.length === 1 ? 'reply' : 'replies' }}</h2>\r\n \r\n <div class=\"comments-list\">\r\n @for (comment of post().comments!; track comment.authorName + comment.timestamp) {\r\n <ds-mobile-comment\r\n [authorName]=\"comment.authorName\"\r\n [authorRole]=\"comment.authorRole\"\r\n [timestamp]=\"comment.timestamp\"\r\n [avatarInitials]=\"comment.avatarInitials\"\r\n [content]=\"comment.content\"\r\n [isLiked]=\"comment.isLiked || false\"\r\n [likeCount]=\"comment.likeCount || 0\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"comment.isOwnComment || false\"\r\n (replyClick)=\"handleReply(comment.authorName, comment.content)\"\r\n (editClick)=\"handleEditComment(comment.authorName, comment.content, comment.timestamp)\"\r\n (longPress)=\"handleCommentLongPress(comment.authorName, comment.content, comment.isOwnComment || false)\" />\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"comments-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"Ingen kommentarer endnu\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">Ingen svar endnu</h3>\r\n <p class=\"empty-state-description\">Vær den første til at svare på dette opslag</p>\r\n </div>\r\n }\r\n \r\n <!-- Bottom spacer for fixed composer -->\r\n <div class=\"composer-spacer\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n \r\n <!-- Fixed comment composer -->\r\n <div class=\"comment-composer-fixed\">\r\n <div class=\"comment-composer\">\r\n <!-- Edit indicator -->\r\n @if (editingComment()) {\r\n <div class=\"edit-indicator\">\r\n <div class=\"edit-indicator-content\">\r\n <ds-icon name=\"remixEditLine\" size=\"16px\" />\r\n <span class=\"edit-text\">Redigerer kommentar</span>\r\n </div>\r\n <button class=\"cancel-edit\" (click)=\"cancelEdit()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n } @else if (replyingTo()) {\r\n <!-- Reply indicator -->\r\n <div class=\"reply-indicator\">\r\n <div class=\"reply-indicator-content\">\r\n <ds-icon name=\"remixReplyLine\" size=\"16px\" />\r\n <span class=\"reply-to-text\">\r\n Svarer til <span class=\"reply-author\">{{ replyingTo()!.authorName }}</span>\r\n </span>\r\n </div>\r\n <button class=\"cancel-reply\" (click)=\"cancelReply()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n }\r\n \r\n <div class=\"composer-content\">\r\n <ds-avatar\r\n [initials]=\"currentUserInitials()\"\r\n [type]=\"'initials'\"\r\n size=\"md\"\r\n />\r\n <div class=\"composer-input-wrapper\">\r\n <!-- Mention menu -->\r\n @if (showMentionMenu() && filteredUsers().length > 0 && !editingComment()) {\r\n <div class=\"mention-menu\">\r\n @for (user of filteredUsers(); track user.name) {\r\n <button \r\n class=\"mention-menu-item\" \r\n (click)=\"selectMention(user.name)\">\r\n <ds-avatar \r\n [initials]=\"user.initials\"\r\n [type]=\"'initials'\"\r\n size=\"sm\" />\r\n <div class=\"mention-user-info\">\r\n <span class=\"mention-user-name\">{{ user.name }}</span>\r\n <span class=\"mention-user-role\">{{ user.role }}</span>\r\n </div>\r\n </button>\r\n }\r\n </div>\r\n }\r\n \r\n <textarea\r\n #commentInput\r\n class=\"composer-input\"\r\n [placeholder]=\"editingComment() ? 'Rediger din kommentar...' : (replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...')\"\r\n [(ngModel)]=\"commentText\"\r\n (input)=\"handleInput($event)\"\r\n (focus)=\"showKeyboard()\"\r\n (click)=\"showKeyboard()\"\r\n rows=\"1\"\r\n ></textarea>\r\n </div>\r\n @if (commentText().trim().length > 0) {\r\n <ds-icon-button\r\n icon=\"remixCheckLine\"\r\n variant=\"primary\"\r\n size=\"sm\"\r\n (clicked)=\"submitComment()\"\r\n aria-label=\"Send kommentar\"\r\n class=\"send-button-fixed\">\r\n </ds-icon-button>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: relative;\r\n height: 100%;\r\n width: 100%;\r\n }\r\n\r\n .post-modal-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .post-modal-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n min-height: 100%;\r\n min-height: 100dvh; /* Use dynamic viewport height for proper iOS safe area handling */\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .post-modal-header {\r\n position: sticky;\r\n top: 0;\r\n z-index: 10;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 16px;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 72px;\r\n /* No padding needed - StatusBar.setOverlaysWebView(false) handles all spacing */\r\n }\r\n\r\n .post-author-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n /* Author name and meta styles imported from mobile-common.css */\r\n\r\n .author-meta .separator {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n\r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .post-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n width: 100%;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n padding: 16px 0 20px 0;\r\n flex: 1;\r\n }\r\n \r\n .post-section {\r\n width: 100%;\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 0 16px 0;\r\n }\r\n\r\n .post-content-only {\r\n font-size: var(--font-size-sm);\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin-bottom: 16px;\r\n padding: 0 20px;\r\n }\r\n \r\n .post-content-only post-media {\r\n margin-top: 16px;\r\n }\r\n\r\n .post-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 0 20px;\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n .comments-section {\r\n display: flex;\r\n flex-direction: column;\r\n margin-left: 0;\r\n margin-right: 0;\r\n padding: 0 20px;\r\n padding-bottom: 0;\r\n }\r\n \r\n .comments-header {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0 0 16px 0;\r\n padding-left: 0;\r\n padding-right: 0;\r\n }\r\n \r\n .comments-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Empty State */\r\n .comments-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n margin-bottom: 24px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0 0 8px 0;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-text-secondary, #737373);\r\n margin: 0;\r\n }\r\n \r\n .composer-spacer {\r\n /* Match full composer height:\r\n - Border: 1px\r\n - Top padding: 12px\r\n - Composer content: ~56px (avatar + input wrapper)\r\n - Bottom padding: 12px + safe area\r\n Total: ~81px + safe area */\r\n height: calc(81px + env(safe-area-inset-bottom, 0px));\r\n }\r\n \r\n .bottom-spacer {\r\n height: 0px;\r\n }\r\n\r\n /* Fixed Comment Composer Container */\r\n .comment-composer-fixed {\r\n position: fixed;\r\n bottom: 48px; /* Compensate for modal's margin-top: 48px */\r\n left: 0;\r\n right: 0;\r\n z-index: 1000;\r\n pointer-events: none;\r\n /* Slide up with keyboard on native apps */\r\n transform: translateY(calc(-1 * var(--keyboard-height, 0px)));\r\n transition: transform 0.3s ease-out;\r\n /* Ensure it's within the modal viewport */\r\n max-width: 100vw;\r\n }\r\n\r\n /* Comment Composer */\r\n .comment-composer {\r\n pointer-events: auto;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-top: 1px solid var(--border-color-default);\r\n padding: 12px 16px;\r\n /* Use dynamic viewport height safe area - matches tabs fix */\r\n /* For web browsers: 12px default; for native iOS: env(safe-area-inset-bottom) */\r\n padding-bottom: max(12px, env(safe-area-inset-bottom, 0px));\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n /* White box shadow to cover content gap between keyboard and composer */\r\n box-shadow: 100px 150px 0 150px var(--color-background-neutral-primary, #ffffff);\r\n }\r\n \r\n /* Edit indicator */\r\n .edit-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-brand-subtle, #f0edfe);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n \r\n .edit-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n color: var(--color-brand-base, #6B5FF5);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .edit-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-brand-base, #6B5FF5);\r\n }\r\n \r\n .cancel-edit {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-brand-base, #6B5FF5);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .cancel-edit:active {\r\n background: var(--color-brand-subtle, #e0dbfe);\r\n }\r\n \r\n /* Reply indicator */\r\n .reply-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n \r\n .reply-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n color: var(--color-text-secondary, #737373);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .reply-to-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .reply-author {\r\n color: var(--color-brand-base, #6B5FF5);\r\n font-weight: 600;\r\n }\r\n \r\n .cancel-reply {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-text-secondary, #737373);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .cancel-reply:active {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n @keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n \r\n .composer-content {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 12px;\r\n width: 100%;\r\n position: relative;\r\n }\r\n \r\n .composer-content ds-avatar {\r\n position: relative;\r\n top: 6px;\r\n }\r\n \r\n .composer-input-wrapper {\r\n flex: 1;\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 8px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 24px;\r\n padding: 12px 16px;\r\n padding-right: 48px; /* Extra padding for fixed send button */\r\n min-height: 44px;\r\n position: relative;\r\n }\r\n \r\n /* Mention menu */\r\n .mention-menu {\r\n position: absolute;\r\n bottom: 100%;\r\n left: 0;\r\n right: 0;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-radius: 12px;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n margin-bottom: 8px;\r\n max-height: 200px;\r\n overflow-y: auto;\r\n z-index: 10;\r\n animation: slideUp 0.2s ease-out;\r\n }\r\n \r\n @keyframes slideUp {\r\n from {\r\n opacity: 0;\r\n transform: translateY(10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n \r\n .mention-menu-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px;\r\n border: none;\r\n background: none;\r\n width: 100%;\r\n text-align: left;\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n border-bottom: 1px solid var(--border-color-default);\r\n }\r\n \r\n .mention-menu-item:last-child {\r\n border-bottom: none;\r\n }\r\n \r\n .mention-menu-item:active {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n .mention-user-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .mention-user-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .mention-user-role {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n \r\n .composer-input {\r\n flex: 1;\r\n border: none;\r\n background: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n outline: none;\r\n resize: none;\r\n min-height: 20px;\r\n max-height: 120px;\r\n overflow-y: auto;\r\n padding: 0;\r\n margin: 0;\r\n }\r\n \r\n .composer-input::placeholder {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n font-size: var(--font-size-sm);\r\n }\r\n \r\n /* Style the send button (ds-icon-button) - positioned in top right corner */\r\n .send-button-fixed {\r\n position: absolute;\r\n top: 6px;\r\n right: 6px;\r\n z-index: 10;\r\n flex-shrink: 0;\r\n animation: slideInFromRight 0.2s ease-out;\r\n }\r\n \r\n .send-button-fixed::ng-deep button {\r\n width: 32px !important;\r\n height: 32px !important;\r\n min-width: 32px !important;\r\n min-height: 32px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Keep old style for reference but won't be used */\r\n .composer-input-wrapper ds-icon-button {\r\n flex-shrink: 0;\r\n animation: slideInFromRight 0.2s ease-out;\r\n }\r\n \r\n .composer-input-wrapper ds-icon-button::ng-deep button {\r\n width: 32px !important;\r\n height: 32px !important;\r\n min-width: 32px !important;\r\n min-height: 32px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Slide in animation from right */\r\n @keyframes slideInFromRight {\r\n from {\r\n opacity: 0;\r\n transform: translateX(20px) scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0) scale(1);\r\n }\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .post-detail-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobilePostDetailModalComponent implements AfterViewInit, OnDestroy {\r\n // Post data passed from service\r\n @Input() postData!: PostDetailData;\r\n \r\n // ViewChild for comment input\r\n @ViewChild('commentInput') commentInput?: ElementRef<HTMLTextAreaElement>;\r\n\r\n // Signal for reactive post data\r\n post = signal<PostDetailData>({\r\n postId: '',\r\n authorName: '',\r\n authorRole: '',\r\n timestamp: '',\r\n content: '',\r\n comments: []\r\n });\r\n\r\n // Comment composer state\r\n commentText = signal('');\r\n currentUserInitials = signal('LM');\r\n replyingTo = signal<{ authorName: string; content: string } | null>(null);\r\n editingComment = signal<{ authorName: string; originalContent: string; timestamp: string } | null>(null);\r\n \r\n // Mention menu state\r\n showMentionMenu = signal(false);\r\n mentionQuery = signal('');\r\n \r\n // Get available users to mention (post author + commenters)\r\n availableUsers = computed(() => {\r\n const post = this.post();\r\n const users: Array<{ name: string; initials: string; role: string }> = [];\r\n \r\n // Add post author\r\n users.push({\r\n name: post.authorName,\r\n initials: post.avatarInitials || post.authorName.split(' ').map(n => n[0]).join(''),\r\n role: post.authorRole\r\n });\r\n \r\n // Add unique commenters\r\n const commenterNames = new Set<string>();\r\n post.comments?.forEach(comment => {\r\n if (!commenterNames.has(comment.authorName)) {\r\n commenterNames.add(comment.authorName);\r\n users.push({\r\n name: comment.authorName,\r\n initials: comment.avatarInitials,\r\n role: comment.authorRole\r\n });\r\n }\r\n });\r\n \r\n return users;\r\n });\r\n \r\n // Filtered users based on mention query\r\n filteredUsers = computed(() => {\r\n const query = this.mentionQuery().toLowerCase();\r\n if (!query) return this.availableUsers();\r\n return this.availableUsers().filter(user => \r\n user.name.toLowerCase().includes(query)\r\n );\r\n });\r\n\r\n constructor(\r\n private modalController: ModalController,\r\n private lightbox: DsMobileLightboxService,\r\n private bottomSheet: DsMobileBottomSheetService\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize post data from input\r\n if (this.postData) {\r\n this.post.set(this.postData);\r\n }\r\n \r\n // Set up keyboard listeners to update CSS variable for composer positioning\r\n this.setupKeyboardListeners();\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Auto-focus comment input if requested\r\n if (this.postData?.focusComment) {\r\n // Small delay to ensure modal animation is complete\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }, 300);\r\n }\r\n }\r\n \r\n ngOnDestroy(): void {\r\n // Clean up keyboard listeners when modal is destroyed\r\n this.cleanupKeyboardListeners();\r\n }\r\n \r\n /**\r\n * Set up keyboard event listeners to adjust composer position\r\n * The CSS uses --keyboard-height variable to translate the composer up\r\n */\r\n private setupKeyboardListeners(): void {\r\n Keyboard.addListener('keyboardWillShow', (info) => {\r\n document.documentElement.style.setProperty('--keyboard-height', `${info.keyboardHeight}px`);\r\n }).catch(e => console.log('Keyboard listeners not available:', e));\r\n \r\n Keyboard.addListener('keyboardWillHide', () => {\r\n document.documentElement.style.setProperty('--keyboard-height', '0px');\r\n }).catch(e => console.log('Keyboard listeners not available:', e));\r\n }\r\n \r\n /**\r\n * Clean up keyboard event listeners\r\n */\r\n private cleanupKeyboardListeners(): void {\r\n Keyboard.removeAllListeners().catch(e => console.log('Keyboard cleanup not available:', e));\r\n }\r\n\r\n /**\r\n * Show the keyboard when user interacts with input\r\n */\r\n showKeyboard(): void {\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }\r\n \r\n /**\r\n * Focus the comment input when comment icon is tapped\r\n */\r\n focusCommentInput(): void {\r\n // Focus the input\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }\r\n \r\n /**\r\n * Handle input changes and detect @ mentions\r\n */\r\n handleInput(event: Event): void {\r\n const textarea = event.target as HTMLTextAreaElement;\r\n const text = textarea.value;\r\n const cursorPosition = textarea.selectionStart || 0;\r\n \r\n // Auto-resize textarea\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n \r\n // Find the last @ before cursor\r\n const textBeforeCursor = text.substring(0, cursorPosition);\r\n const lastAtIndex = textBeforeCursor.lastIndexOf('@');\r\n \r\n if (lastAtIndex !== -1) {\r\n // Check if there's a space after @\r\n const textAfterAt = textBeforeCursor.substring(lastAtIndex + 1);\r\n const hasSpace = textAfterAt.includes(' ');\r\n \r\n if (!hasSpace) {\r\n // Show mention menu\r\n this.showMentionMenu.set(true);\r\n this.mentionQuery.set(textAfterAt);\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n }\r\n \r\n /**\r\n * Select a user from mention menu - show as reply indicator instead of inline mention\r\n */\r\n selectMention(userName: string): void {\r\n // Set as reply (similar to clicking Reply on a comment)\r\n this.replyingTo.set({ authorName: userName, content: '' });\r\n \r\n // Clear the @ from the input\r\n const currentText = this.commentText();\r\n const textWithoutMention = currentText.substring(0, currentText.lastIndexOf('@'));\r\n this.commentText.set(textWithoutMention);\r\n \r\n // Hide mention menu\r\n this.showMentionMenu.set(false);\r\n \r\n // Focus back on input\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n }, 0);\r\n }\r\n \r\n /**\r\n * Handle reply to a comment\r\n */\r\n handleReply(authorName: string, content: string): void {\r\n this.replyingTo.set({ authorName, content });\r\n // Focus the input and show keyboard\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n this.showKeyboard();\r\n }, 100);\r\n }\r\n \r\n /**\r\n * Cancel reply\r\n */\r\n cancelReply(): void {\r\n this.replyingTo.set(null);\r\n }\r\n \r\n /**\r\n * Cancel edit\r\n */\r\n cancelEdit(): void {\r\n this.editingComment.set(null);\r\n this.commentText.set('');\r\n }\r\n \r\n /**\r\n * Handle edit comment\r\n */\r\n handleEditComment(authorName: string, originalContent: string, timestamp: string): void {\r\n // Clear reply state if active\r\n this.replyingTo.set(null);\r\n \r\n // Remove @mention from the content if it exists\r\n let contentToEdit = originalContent;\r\n const mentionMatch = originalContent.match(/^@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\s+/);\r\n if (mentionMatch) {\r\n contentToEdit = originalContent.substring(mentionMatch[0].length);\r\n }\r\n \r\n // Set edit state\r\n this.editingComment.set({ authorName, originalContent, timestamp });\r\n \r\n // Populate the input with existing content\r\n this.commentText.set(contentToEdit);\r\n \r\n // Focus the input, show keyboard, and auto-resize\r\n setTimeout(() => {\r\n if (this.commentInput?.nativeElement) {\r\n const textarea = this.commentInput.nativeElement;\r\n textarea.focus();\r\n \r\n // Auto-resize textarea to fit content\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n \r\n this.showKeyboard();\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n\r\n /**\r\n * Submit a comment\r\n */\r\n submitComment(): void {\r\n const text = this.commentText().trim();\r\n if (!text) return;\r\n\r\n const currentPost = this.post();\r\n \r\n // Check if we're editing an existing comment\r\n if (this.editingComment()) {\r\n console.log('[PostDetailModal] Updating comment:', text);\r\n \r\n const editing = this.editingComment()!;\r\n \r\n // Update the existing comment\r\n const updatedComments = currentPost.comments?.map(comment => {\r\n if (comment.authorName === editing.authorName && \r\n comment.content === editing.originalContent &&\r\n comment.timestamp === editing.timestamp) {\r\n return {\r\n ...comment,\r\n content: text,\r\n timestamp: 'Just now (edited)'\r\n };\r\n }\r\n return comment;\r\n });\r\n \r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments\r\n });\r\n \r\n // Clear edit state\r\n this.editingComment.set(null);\r\n } else {\r\n // Create new comment\r\n console.log('[PostDetailModal] Submitting comment:', text);\r\n \r\n const newComment: CommentData = {\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'You',\r\n timestamp: 'Just now',\r\n avatarInitials: this.currentUserInitials(),\r\n content: this.replyingTo() \r\n ? `@${this.replyingTo()!.authorName} ${text}`\r\n : text,\r\n isLiked: false,\r\n likeCount: 0,\r\n isOwnComment: true\r\n };\r\n\r\n // Add comment to the list\r\n const updatedComments = [...(currentPost.comments || []), newComment];\r\n \r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments,\r\n commentCount: updatedComments.length\r\n });\r\n \r\n // Clear reply state\r\n this.replyingTo.set(null);\r\n }\r\n\r\n // Clear the input\r\n this.commentText.set('');\r\n this.showMentionMenu.set(false);\r\n \r\n // Reset textarea height to initial state\r\n if (this.commentInput?.nativeElement) {\r\n this.commentInput.nativeElement.style.height = 'auto';\r\n }\r\n \r\n // Blur the input to hide the keyboard\r\n this.commentInput?.nativeElement.blur();\r\n \r\n // Hide keyboard explicitly\r\n Keyboard.hide().catch(e => console.log('Keyboard.hide() not available'));\r\n\r\n // In a real app, you would also send this to your backend\r\n // this.commentService.addComment(currentPost.postId, text);\r\n }\r\n\r\n /**\r\n * Open image in lightbox\r\n */\r\n openImageLightbox(): void {\r\n const postData = this.post();\r\n \r\n if (!postData.imageSrc) return;\r\n\r\n const authorMeta: LightboxAuthor = {\r\n name: postData.authorName,\r\n role: postData.authorRole,\r\n avatarInitials: postData.avatarInitials || '',\r\n avatarType: postData.avatarType || 'initials',\r\n avatarSrc: postData.avatarSrc || '',\r\n timestamp: postData.timestamp\r\n };\r\n\r\n this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: postData.imageSrc,\r\n alt: postData.imageAlt || 'Post image',\r\n title: postData.imageAlt || '',\r\n description: postData.content,\r\n isLiked: postData.isLiked || false,\r\n likeCount: postData.likeCount || 0,\r\n commentCount: postData.commentCount || 0\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false,\r\n showInfo: true\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a comment to show action sheet\r\n */\r\n async handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobileCommentActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnComment\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as CommentActionResult).action;\r\n const currentPost = this.post();\r\n \r\n switch (action) {\r\n case 'like':\r\n console.log('Like comment by', authorName);\r\n // Find and toggle like on the comment\r\n const updatedComments = currentPost.comments?.map(comment => {\r\n if (comment.authorName === authorName && comment.content === content) {\r\n const isLiked = !comment.isLiked;\r\n return {\r\n ...comment,\r\n isLiked,\r\n likeCount: isLiked ? (comment.likeCount || 0) + 1 : Math.max(0, (comment.likeCount || 0) - 1)\r\n };\r\n }\r\n return comment;\r\n });\r\n this.post.set({ ...currentPost, comments: updatedComments });\r\n break;\r\n case 'reply':\r\n console.log('Reply to comment by', authorName);\r\n this.handleReply(authorName, content);\r\n break;\r\n case 'edit':\r\n console.log('Edit comment by', authorName);\r\n // Find the full comment data to get timestamp\r\n const commentToEdit = currentPost.comments?.find(\r\n comment => comment.authorName === authorName && comment.content === content\r\n );\r\n if (commentToEdit) {\r\n this.handleEditComment(authorName, content, commentToEdit.timestamp);\r\n }\r\n break;\r\n case 'delete':\r\n console.log('Delete comment by', authorName);\r\n // Show confirmation before deleting\r\n if (confirm('Are you sure you want to delete this comment?')) {\r\n const updatedCommentsAfterDelete = currentPost.comments?.filter(\r\n comment => !(comment.authorName === authorName && comment.content === content)\r\n );\r\n this.post.set({ \r\n ...currentPost, \r\n comments: updatedCommentsAfterDelete,\r\n commentCount: updatedCommentsAfterDelete?.length || 0\r\n });\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobilePostDetailModalComponent, PostDetailData } from './ds-mobile-post-detail-modal';\r\n\r\n/**\r\n * DsMobilePostDetailModalService\r\n * \r\n * Service for displaying post details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * Follows the same pattern as DsMobileLightboxService for consistent behavior.\r\n * \r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Like/comment actions\r\n * - Image lightbox integration\r\n * - Native modal animations\r\n * - Safe area support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n * \r\n * async openPost() {\r\n * await this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * authorRole: 'Tenant',\r\n * timestamp: '2h ago',\r\n * avatarInitials: 'JD',\r\n * content: 'Just moved into my new apartment!',\r\n * isLiked: false,\r\n * likeCount: 42,\r\n * commentCount: 12,\r\n * comments: [\r\n * {\r\n * authorName: 'Jane Smith',\r\n * authorRole: 'Tenant',\r\n * timestamp: '1h ago',\r\n * avatarInitials: 'JS',\r\n * content: 'Welcome to the community!'\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobilePostDetailModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the post detail modal\r\n * \r\n * @param postData Post data to display\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(postData: PostDetailData): Promise<void> {\r\n console.log('[PostDetailModal] Opening with data:', postData);\r\n \r\n const modal = await this.modalController.create({\r\n component: DsMobilePostDetailModalComponent,\r\n componentProps: {\r\n postData: postData\r\n },\r\n cssClass: 'ds-post-detail-modal',\r\n mode: 'ios',\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n // Control the presenting element animation\r\n enterAnimation: undefined, // Use default\r\n leaveAnimation: undefined // Use default\r\n });\r\n\r\n console.log('[PostDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[PostDetailModal] Modal presented');\r\n }\r\n\r\n /**\r\n * Close the currently open post detail modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","/**\r\n * Mobile Post Detail Modal Module\r\n * \r\n * Service and component for displaying posts in a modal\r\n */\r\n\r\nexport * from './ds-mobile-post-detail-modal';\r\nexport * from './ds-mobile-post-detail-modal.service';\r\n\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileHandbookFolderMiniComponent\r\n * \r\n * A minimized folder icon component for use in headers and small spaces.\r\n * Simplified version without animations or page sheets - just folder and icon.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder-mini\r\n * [variant]=\"'pink'\"\r\n * [iconName]=\"'remixLightbulbLine'\">\r\n * </ds-mobile-handbook-folder-mini>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder-mini',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n width: 32px;\r\n height: 32px;\r\n flex-shrink: 0;\r\n }\r\n \r\n .mini-folder-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n .mini-folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n .mini-folder-back {\r\n height: 28px;\r\n border-radius: 0px 4px 4px 4px;\r\n position: relative;\r\n margin-top: -1px;\r\n }\r\n \r\n .mini-folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 24px;\r\n border-radius: 4px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 2;\r\n box-shadow: inset 0 8px 8px rgba(255, 255, 255, 0.2), \r\n inset 0 0.5px 0.5px rgba(255, 255, 255, 0.3);\r\n }\r\n `],\r\n template: `\r\n <div class=\"mini-folder-container\">\r\n <!-- Folder Tab SVG -->\r\n <svg \r\n class=\"mini-folder-tab\" \r\n width=\"101\" \r\n height=\"24\" \r\n viewBox=\"0 0 101 24\" \r\n fill=\"none\" \r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path \r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\" \r\n [attr.fill]=\"getColorVar('strong')\"/>\r\n </svg>\r\n \r\n <!-- Folder Back -->\r\n <div class=\"mini-folder-back\" [style.background-color]=\"getColorVar('strong')\">\r\n <!-- Folder Front -->\r\n <div \r\n class=\"mini-folder-front\" \r\n [style.background-color]=\"getColorVar('base')\">\r\n <ds-icon \r\n [name]=\"iconName\" \r\n [size]=\"'14px'\"\r\n [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileHandbookFolderMiniComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n */\r\n @Input() variant: string = 'light-purple';\r\n \r\n /**\r\n * Icon name from the design system icon library\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n \r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n 'success': 'success',\r\n 'warning': 'warning',\r\n 'destructive': 'destructive',\r\n 'blue': 'blue',\r\n 'light-purple': 'light-purple',\r\n 'pink': 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n 'orange': 'orange',\r\n 'lime-green': 'lime-green',\r\n 'grey': 'grey'\r\n };\r\n \r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileFileAttachmentComponent\r\n * \r\n * File attachment display for various document types.\r\n * Shows file info card with icon, filename, and file size.\r\n * Supports PDF and generic document formats.\r\n * Emits click event to open file in viewer.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-file-attachment\r\n * [fileName]=\"'Document.pdf'\"\r\n * [fileSize]=\"'1.2 MB'\"\r\n * [variant]=\"'pdf'\"\r\n * (fileClick)=\"openFile()\">\r\n * </ds-mobile-file-attachment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-file-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .file-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .file-avatar.pdf::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .file-avatar.doc::ng-deep .avatar--icon {\r\n background-color: var(--color-blue-base, #3B82F6) !important;\r\n }\r\n \r\n .file-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .file-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .file-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"file-avatar\" [class.pdf]=\"variant() === 'pdf'\" [class.doc]=\"variant() === 'doc'\">\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"getIconName()\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"file-info\">\r\n <div class=\"file-name\">{{ fileName() }}</div>\r\n @if (fileSize()) {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>\r\n } @else {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }}</div>\r\n }\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"20px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class DsMobileFileAttachmentComponent {\r\n /**\r\n * File name\r\n */\r\n fileName = input<string>('Document');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * File type variant\r\n * - 'pdf' - PDF document (red icon)\r\n * - 'doc' - Generic document (blue icon)\r\n */\r\n variant = input<'pdf' | 'doc'>('doc');\r\n \r\n /**\r\n * Emits when the file attachment is clicked\r\n */\r\n fileClick = output<void>();\r\n \r\n /**\r\n * Get the appropriate icon name based on variant\r\n */\r\n getIconName(): string {\r\n return this.variant() === 'pdf' ? 'remixFileTextLine' : 'remixAttachmentLine';\r\n }\r\n \r\n /**\r\n * Get the file type label based on variant\r\n */\r\n getFileTypeLabel(): string {\r\n return this.variant() === 'pdf' ? 'PDF' : 'DOC';\r\n }\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.fileClick.emit();\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n input,\r\n AfterViewInit,\r\n OnDestroy,\r\n ElementRef,\r\n ViewChild,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport Swiper from 'swiper';\r\n\r\n/**\r\n * DsMobileSwiperComponent\r\n * \r\n * A reusable swiper/carousel component with configurable child width and spacing.\r\n * \r\n * Features:\r\n * - First slide is left-aligned\r\n * - Middle slides are centered when active\r\n * - Last slide is right-aligned\r\n * - Configurable slide width and gap\r\n * - Content projection via ng-content\r\n * \r\n * Usage:\r\n * ```html\r\n * <ds-mobile-swiper [slideWidth]=\"'75vw'\" [gap]=\"16\">\r\n * <div class=\"swiper-slide\">Slide 1</div>\r\n * <div class=\"swiper-slide\">Slide 2</div>\r\n * <div class=\"swiper-slide\">Slide 3</div>\r\n * </ds-mobile-swiper>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-swiper',\r\n standalone: true,\r\n imports: [CommonModule],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .swiper-container {\r\n width: 100%;\r\n position: relative;\r\n overflow: hidden;\r\n border-radius: 12px;\r\n }\r\n\r\n .swiper-wrapper {\r\n display: flex;\r\n transition-property: transform;\r\n box-sizing: content-box;\r\n }\r\n\r\n :host ::ng-deep .swiper-slide {\r\n flex-shrink: 0;\r\n height: 100%;\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n `]\r\n})\r\nexport class DsMobileSwiperComponent implements AfterViewInit, OnDestroy {\r\n /**\r\n * Width of each slide (e.g., '75vw', '300px', '80%')\r\n */\r\n slideWidth = input<string>('75vw');\r\n\r\n /**\r\n * Gap between slides in pixels\r\n */\r\n gap = input<number>(16);\r\n\r\n @ViewChild('swiperContainer', { static: false }) swiperContainer!: ElementRef;\r\n\r\n private swiperInstance: Swiper | null = null;\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n }, 100);\r\n }\r\n\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) return;\r\n\r\n // Apply slide width to all slides\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.swiper-slide');\r\n slides.forEach((slide: HTMLElement) => {\r\n slide.style.width = this.slideWidth();\r\n });\r\n\r\n this.swiperInstance = new Swiper(this.swiperContainer.nativeElement, {\r\n slidesPerView: 'auto',\r\n spaceBetween: this.gap(),\r\n centeredSlides: true,\r\n centeredSlidesBounds: true,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.swiperInstance) {\r\n this.swiperInstance.destroy();\r\n this.swiperInstance = null;\r\n }\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n signal,\r\n Input,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonContent,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileHandbookFolderMiniComponent } from '../handbook-folder/ds-mobile-handbook-folder-mini';\r\nimport { DsMobileFileAttachmentComponent } from '../file-attachment';\r\nimport { DsMobileContactListItemComponent } from '../contact-list-item';\r\nimport { DsMobileSwiperComponent } from '../swiper';\r\n\r\n/**\r\n * Handbook detail data interface\r\n */\r\nexport interface HandbookDetailData {\r\n title: string;\r\n variant: string;\r\n iconName: string;\r\n itemCount: number;\r\n items?: HandbookItem[];\r\n}\r\n\r\nexport interface HandbookItem {\r\n title: string;\r\n description?: string;\r\n images?: string[];\r\n attachments?: AttachmentItem[];\r\n contacts?: ContactItem[];\r\n}\r\n\r\nexport interface AttachmentItem {\r\n name: string;\r\n type?: string;\r\n}\r\n\r\nexport interface ContactItem {\r\n name: string;\r\n initials: string;\r\n contactPerson?: string;\r\n phoneNumber?: string;\r\n}\r\n\r\n/**\r\n * DsMobileHandbookDetailModalComponent\r\n * \r\n * Modal wrapper for displaying handbook folder details.\r\n * \r\n * Features:\r\n * - Folder content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n * \r\n * This component is typically not used directly - use DsMobileHandbookDetailModalService instead.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonContent,\r\n DsIconButtonComponent,\r\n DsMobileHandbookFolderMiniComponent,\r\n DsMobileFileAttachmentComponent,\r\n DsMobileContactListItemComponent,\r\n DsMobileSwiperComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content [fullscreen]=\"true\" [scrollY]=\"true\" class=\"handbook-modal-content\">\r\n <div class=\"handbook-modal-wrapper\">\r\n <!-- Header -->\r\n <div class=\"handbook-modal-header\">\r\n <div class=\"header-content\">\r\n <!-- Handbook folder info -->\r\n <div class=\"handbook-folder-info\">\r\n <ds-mobile-handbook-folder-mini\r\n [variant]=\"handbook().variant\"\r\n [iconName]=\"handbook().iconName\">\r\n </ds-mobile-handbook-folder-mini>\r\n <div class=\"folder-details\">\r\n <div class=\"folder-name\">{{ handbook().title }}</div>\r\n <div class=\"folder-meta\">\r\n <span>{{ handbook().itemCount }} emner</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Luk\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"handbook-detail-container\">\r\n @if (handbook().items && handbook().items!.length > 0) {\r\n @for (item of getDisplayItems(); track item.title + $index; let isLast = $last) {\r\n <div class=\"handbook-item\" [class.last-item]=\"isLast\">\r\n <div class=\"item-text-group\">\r\n <h2 class=\"item-title\">{{ item.title }}</h2>\r\n \r\n @if (item.description) {\r\n <p class=\"item-description\">{{ item.description }}</p>\r\n }\r\n </div>\r\n \r\n <!-- Images -->\r\n @if (item.images && item.images.length > 0) {\r\n <ds-mobile-swiper [slideWidth]=\"item.images.length === 1 ? '100%' : '60vw'\" [gap]=\"16\">\r\n @for (image of item.images; track image) {\r\n <div class=\"swiper-slide\">\r\n <img \r\n [src]=\"image\" \r\n [alt]=\"item.title\"\r\n class=\"item-image\"\r\n />\r\n </div>\r\n }\r\n </ds-mobile-swiper>\r\n }\r\n \r\n <!-- Contacts -->\r\n @if (item.contacts && item.contacts.length > 0) {\r\n <div class=\"contacts-list\">\r\n @for (contact of item.contacts; track contact.name) {\r\n <ds-mobile-contact-list-item\r\n [name]=\"contact.name\"\r\n [initials]=\"contact.initials\"\r\n [contactPerson]=\"contact.contactPerson || ''\"\r\n [phoneNumber]=\"contact.phoneNumber || ''\"\r\n [clickable]=\"true\"\r\n (contactClick)=\"handleContactClick(contact)\">\r\n </ds-mobile-contact-list-item>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Attachments -->\r\n @if (item.attachments && item.attachments.length > 0) {\r\n <div class=\"attachments-list\">\r\n @for (attachment of item.attachments; track attachment.name) {\r\n <ds-mobile-file-attachment\r\n [fileName]=\"attachment.name\"\r\n [variant]=\"attachment.type === 'pdf' ? 'pdf' : 'doc'\"\r\n (fileClick)=\"handleAttachmentClick(attachment)\">\r\n </ds-mobile-file-attachment>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"handbook-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"No items yet\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">No items yet</h3>\r\n <p class=\"empty-state-description\">This folder is empty</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ion-content>\r\n `,\r\n styles: [`\r\n .handbook-modal-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .handbook-modal-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n min-height: 100%;\r\n min-height: 100dvh;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .handbook-modal-header {\r\n position: sticky;\r\n top: 0;\r\n z-index: 10;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 16px;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 72px;\r\n }\r\n\r\n .handbook-folder-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .folder-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n .folder-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n\r\n .folder-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n\r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .handbook-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n flex: 1;\r\n }\r\n \r\n .handbook-item {\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 24px;\r\n padding: 24px 20px 24px 20px;\r\n border-bottom: 1px solid var(--border-color-default);\r\n }\r\n \r\n .handbook-item.last-item {\r\n border-bottom: none;\r\n }\r\n\r\n .item-text-group {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n\r\n .item-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 16px;\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n }\r\n\r\n .item-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n }\r\n\r\n .item-image {\r\n width: 100%;\r\n height: 280px;\r\n object-fit: cover;\r\n border-radius: 12px;\r\n display: block;\r\n }\r\n\r\n .contacts-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:last-child) {\r\n position: relative;\r\n padding-bottom: 8px;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:first-child) {\r\n padding-top: 8px;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:last-child)::after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: 44px;\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n \r\n .attachments-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n \r\n\r\n /* Empty State */\r\n .handbook-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .handbook-detail-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileHandbookDetailModalComponent {\r\n // Handbook data passed from service\r\n @Input() handbookData!: HandbookDetailData;\r\n \r\n // Signal for reactive handbook data\r\n handbook = signal<HandbookDetailData>({\r\n title: '',\r\n variant: 'light-purple',\r\n iconName: 'remixFolder3Line',\r\n itemCount: 0,\r\n items: []\r\n });\r\n\r\n constructor(\r\n private modalController: ModalController\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize handbook data from input\r\n if (this.handbookData) {\r\n this.handbook.set(this.handbookData);\r\n }\r\n }\r\n\r\n /**\r\n * Split handbook items to enforce content structure rules:\r\n * - Never mix photos and documents (attachments) in the same section\r\n * - Never mix contact persons and attachments together in the same section\r\n * \r\n * This method splits items that violate these rules into multiple display items.\r\n * Each resulting item will have only compatible content types.\r\n */\r\n splitItemsByContentRules(item: HandbookItem): HandbookItem[] {\r\n const displayItems: HandbookItem[] = [];\r\n \r\n const hasImages = item.images && item.images.length > 0;\r\n const hasContacts = item.contacts && item.contacts.length > 0;\r\n const hasAttachments = item.attachments && item.attachments.length > 0;\r\n \r\n // Case 1: Only one type of content - keep as is\r\n const contentTypeCount = [hasImages, hasContacts, hasAttachments].filter(Boolean).length;\r\n if (contentTypeCount <= 1) {\r\n return [item];\r\n }\r\n \r\n // Case 2: Has images + contacts (allowed together) but no attachments\r\n if (hasImages && hasContacts && !hasAttachments) {\r\n return [item];\r\n }\r\n \r\n // Case 3: Violates rules - need to split\r\n \r\n // First item: Text + Images (if present)\r\n if (hasImages) {\r\n displayItems.push({\r\n title: item.title,\r\n description: item.description,\r\n images: item.images\r\n });\r\n }\r\n \r\n // Second item: Text + Contacts (if present and no images shown yet)\r\n if (hasContacts) {\r\n displayItems.push({\r\n title: item.title,\r\n description: hasImages ? undefined : item.description, // Only show description if not shown before\r\n contacts: item.contacts\r\n });\r\n }\r\n \r\n // Third item: Text + Attachments (if present)\r\n if (hasAttachments) {\r\n displayItems.push({\r\n title: item.title,\r\n description: (!hasImages && !hasContacts) ? item.description : undefined, // Only show description if not shown before\r\n attachments: item.attachments\r\n });\r\n }\r\n \r\n return displayItems;\r\n }\r\n \r\n /**\r\n * Get all display items with enforced content structure rules applied\r\n */\r\n getDisplayItems(): HandbookItem[] {\r\n const items = this.handbook().items || [];\r\n const displayItems: HandbookItem[] = [];\r\n \r\n for (const item of items) {\r\n const splitItems = this.splitItemsByContentRules(item);\r\n displayItems.push(...splitItems);\r\n }\r\n \r\n return displayItems;\r\n }\r\n\r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n \r\n /**\r\n * Handle contact click\r\n */\r\n handleContactClick(contact: ContactItem): void {\r\n console.log('Contact clicked:', contact);\r\n // Implement contact action (e.g., show contact details, call, etc.)\r\n }\r\n \r\n /**\r\n * Handle attachment click\r\n */\r\n handleAttachmentClick(attachment: AttachmentItem): void {\r\n console.log('Attachment clicked:', attachment);\r\n // Implement attachment action (e.g., open file viewer, download, etc.)\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileHandbookDetailModalComponent, HandbookDetailData } from './ds-mobile-handbook-detail-modal';\r\n\r\n/**\r\n * DsMobileHandbookDetailModalService\r\n * \r\n * Service for displaying handbook folder details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * \r\n * Features:\r\n * - Full handbook content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal animations\r\n * - Safe area support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private handbookModal: DsMobileHandbookDetailModalService) {}\r\n * \r\n * async openHandbook() {\r\n * await this.handbookModal.open({\r\n * title: 'Utilities',\r\n * variant: 'pink',\r\n * iconName: 'remixLightbulbLine',\r\n * itemCount: 8,\r\n * items: [\r\n * {\r\n * title: 'Hjertestarter',\r\n * description: 'Installed on the 4th floor...',\r\n * images: ['/path/to/image.jpg'],\r\n * contacts: [\r\n * { name: 'Mortensen & Søn ApS', initials: 'M' }\r\n * ]\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileHandbookDetailModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the handbook detail modal\r\n * \r\n * @param handbookData Handbook data to display\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(handbookData: HandbookDetailData): Promise<void> {\r\n console.log('[HandbookDetailModal] Opening with data:', handbookData);\r\n \r\n const modal = await this.modalController.create({\r\n component: DsMobileHandbookDetailModalComponent,\r\n componentProps: {\r\n handbookData: handbookData\r\n },\r\n cssClass: 'ds-handbook-detail-modal',\r\n mode: 'ios',\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n enterAnimation: undefined,\r\n leaveAnimation: undefined\r\n });\r\n\r\n console.log('[HandbookDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[HandbookDetailModal] Modal presented');\r\n }\r\n\r\n /**\r\n * Close the currently open handbook detail modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","import { Component, Input, signal, HostListener } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileHandbookDetailModalService, HandbookDetailData, HandbookItem } from '../handbook-detail-modal';\r\n\r\n/**\r\n * DsMobileHandbookFolderComponent\r\n * \r\n * A visually rich folder component for displaying handbook categories or sections.\r\n * Features a two-layer folder design with customizable colors, icon, item count, and label.\r\n * \r\n * Design Details:\r\n * - Folder back: 72px height with a decorative notch\r\n * - Folder front: 64px height overlaying the back\r\n * - Item count displayed in bottom-left corner\r\n * - Icon displayed in bottom-right corner\r\n * - Label text centered below the folder\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder\r\n * [colorBase]=\"'#d244cf'\"\r\n * [colorWeak]=\"'#f9e6f9'\"\r\n * [iconName]=\"'remixLightbulbLine'\"\r\n * [itemCount]=\"8\"\r\n * [label]=\"'Utilities'\">\r\n * </ds-mobile-handbook-folder>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n :host {\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 16px;\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n padding: 16px;\r\n border-radius: 16px;\r\n background: var(--color-background-neutral-secondary, #f0f0f0);\r\n transition: background 0.2s ease;\r\n }\r\n \r\n :host:active {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n @media (hover: hover) {\r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n }\r\n \r\n .folder-container {\r\n position: relative;\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n perspective: 800px;\r\n -webkit-perspective: 800px;\r\n max-width: 160px;\r\n /* Safari optimization: Ensure proper 3D rendering context */\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n }\r\n \r\n .folder-container.open .page-sheet {\r\n -webkit-transform: translateY(-8px);\r\n transform: translateY(-8px);\r\n transition-delay: 0.2s;\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(1) {\r\n -webkit-transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(2) {\r\n -webkit-transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(3) {\r\n -webkit-transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(4) {\r\n -webkit-transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(5) {\r\n -webkit-transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(6) {\r\n -webkit-transform: scale(0.90) translateY(-28px) rotateX(0deg) translateZ(0.1px);\r\n transform: scale(0.90) translateY(-28px) rotateX(0.1px);\r\n }\r\n \r\n .folder-container.open .folder-front {\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n }\r\n \r\n .folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n .folder-back {\r\n height: 128px;\r\n border-radius: 0px 12px 12px 12px;\r\n position: relative;\r\n margin-top: -1px;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Force GPU acceleration */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n }\r\n \r\n .page-sheet {\r\n position: absolute;\r\n width: 80%;\r\n height: 120px;\r\n background: #ffffff;\r\n border-radius: 8px;\r\n box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);\r\n border: 1px solid var(--border-color-default);\r\n transition: transform 0.3s ease-out;\r\n -webkit-transition: -webkit-transform 0.3s ease-out;\r\n left: 10%;\r\n /* Safari optimization: Force hardware acceleration and proper 3D rendering */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Prevent subpixel rendering issues */\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Ensure proper layer creation */\r\n will-change: transform;\r\n }\r\n \r\n .page-sheet:nth-child(1) {\r\n bottom: 2px;\r\n z-index: 6;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(1) translateZ(0.1px);\r\n transform: scale(1) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(2) {\r\n bottom: 8px;\r\n z-index: 5;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.98) translateZ(0.1px);\r\n transform: scale(0.98) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(3) {\r\n bottom: 14px;\r\n z-index: 4;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.96) translateZ(0.1px);\r\n transform: scale(0.96) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(4) {\r\n bottom: 20px;\r\n z-index: 3;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.94) translateZ(0.1px);\r\n transform: scale(0.94) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(5) {\r\n bottom: 26px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.92) translateZ(0.1px);\r\n transform: scale(0.92) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(6) {\r\n bottom: 32px;\r\n z-index: 1;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.90) translateZ(0.1px);\r\n transform: scale(0.90) translateZ(0.1px);\r\n }\r\n \r\n .folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 116px;\r\n border-radius: 12px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 8px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n transition: transform 0.4s ease-in-out, -webkit-transform 0.4s ease-in-out;\r\n -webkit-transition: -webkit-transform 0.4s ease-in-out;\r\n will-change: transform;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Use more specific transform to avoid render glitches */\r\n -webkit-transform: rotateX(-20deg) translateZ(0.1px);\r\n transform: rotateX(-20deg) translateZ(0.1px);\r\n /* Safari optimization: Force layer creation for smoother animations */\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n box-shadow: inset 0 64px 48px rgba(255, 255, 255, 0.2), \r\n inset 0 2px 4px rgba(255, 255, 255, 0.3),\r\n inset 0 1px 1px rgba(255, 255, 255, 0.3);\r\n }\r\n \r\n .item-count {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n \r\n .item-count-label {\r\n letter-spacing: 0.5px;\r\n }\r\n \r\n .folder-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .folder-label-container {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n \r\n .folder-label {\r\n text-align: center;\r\n }\r\n `],\r\n template: `\r\n <div class=\"folder-container\" \r\n [class.open]=\"isOpen()\">\r\n <!-- Folder Tab SVG -->\r\n <svg \r\n class=\"folder-tab\" \r\n width=\"101\" \r\n height=\"24\" \r\n viewBox=\"0 0 101 24\" \r\n fill=\"none\" \r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path \r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\" \r\n [attr.fill]=\"getColorVar('strong')\"/>\r\n </svg>\r\n \r\n <!-- Folder Back -->\r\n <div class=\"folder-back\" [style.background-color]=\"getColorVar('strong')\">\r\n <!-- Page Sheets -->\r\n @for (sheet of getPageSheets(); track $index) {\r\n <div class=\"page-sheet\"></div>\r\n }\r\n \r\n <!-- Folder Front -->\r\n <div \r\n class=\"folder-front\" \r\n [style.--border-color]=\"getColorVar('strong')\"\r\n [style.background-color]=\"getColorVar('base')\">\r\n <!-- Icon (Centered) -->\r\n <div class=\"folder-icon\">\r\n <ds-icon \r\n [name]=\"iconName\" \r\n [size]=\"'32px'\"\r\n [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Label and Item Count -->\r\n <div class=\"folder-label-container\">\r\n <div class=\"folder-label ui-sm-semiBold\">{{ label }}</div>\r\n <div class=\"item-count ui-sm-regular\" [style.color]=\"'var(--color-text-secondary, #6b7280)'\">\r\n <span>{{ itemCount }}</span>\r\n <span class=\"item-count-label\">emner</span>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileHandbookFolderComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n * Example: 'pink', 'success', 'blue'\r\n */\r\n @Input() variant: string = 'light-purple';\r\n \r\n /**\r\n * Icon name from the design system icon library\r\n * Example: 'remixLightbulbLine', 'remixFolder3Line'\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n \r\n /**\r\n * Number of items in the folder\r\n */\r\n @Input() itemCount: number = 0;\r\n \r\n /**\r\n * Label text displayed below the folder\r\n */\r\n @Input() label: string = 'Folder';\r\n \r\n /**\r\n * Optional items data for the handbook folder\r\n */\r\n @Input() items?: HandbookItem[];\r\n \r\n /**\r\n * Track open/closed state for animation\r\n */\r\n isOpen = signal(false);\r\n \r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n 'success': 'success',\r\n 'warning': 'warning',\r\n 'destructive': 'destructive',\r\n 'blue': 'blue',\r\n 'light-purple': 'light-purple',\r\n 'pink': 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n 'orange': 'orange',\r\n 'lime-green': 'lime-green',\r\n 'grey': 'grey'\r\n };\r\n \r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n \r\n /**\r\n * Open folder animation\r\n */\r\n @HostListener('mouseenter')\r\n open(): void {\r\n this.isOpen.set(true);\r\n }\r\n \r\n /**\r\n * Close folder animation\r\n */\r\n @HostListener('mouseleave')\r\n close(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle touch start - open animation\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n onTouchStart(event: TouchEvent): void {\r\n this.isOpen.set(true);\r\n }\r\n \r\n /**\r\n * Handle touch end - close animation\r\n */\r\n @HostListener('touchend')\r\n onTouchEnd(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle touch cancel - close animation\r\n */\r\n @HostListener('touchcancel')\r\n onTouchCancel(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle click - open modal\r\n */\r\n @HostListener('click')\r\n async onClick(): Promise<void> {\r\n const handbookData: HandbookDetailData = {\r\n title: this.label,\r\n variant: this.variant,\r\n iconName: this.iconName,\r\n itemCount: this.itemCount,\r\n items: this.items\r\n };\r\n\r\n await this.handbookModal.open(handbookData);\r\n }\r\n \r\n /**\r\n * Calculate the number of page sheets to display\r\n * Max 6 sheets regardless of item count\r\n */\r\n getPageSheets(): number[] {\r\n const count = Math.min(this.itemCount, 6);\r\n return Array(count).fill(0);\r\n }\r\n\r\n constructor(\r\n private handbookModal: DsMobileHandbookDetailModalService\r\n ) {}\r\n}\r\n\r\n","// Mobile Page Components\r\nexport * from './page-main';\r\nexport * from './page-details';\r\n\r\n// Mobile Content Components\r\nexport * from './content';\r\nexport * from './header-content';\r\n\r\n// Mobile Community Components\r\nexport * from './post-card';\r\nexport * from './comment';\r\nexport * from './post-composer';\r\n\r\n// Mobile List Components\r\nexport * from './list-item';\r\nexport { DsMobileInteractiveListItemPostComponent, PostPdfAttachmentComponent } from './interactive-list-item-post';\r\nexport { DsMobileInteractiveListItemInquiryComponent } from './interactive-list-item-inquiry';\r\nexport { DsMobileInteractiveListItemMessageComponent } from './interactive-list-item-message';\r\nexport { DsMobileContactListItemComponent } from './contact-list-item';\r\n\r\n// Mobile Layout Components\r\nexport { DsMobileAppLayoutComponent, type HeaderVariant } from './app-layout';\r\nexport { DsMobileTabsComponent, type TabConfig } from './tabs';\r\n\r\n// Mobile Bottom Sheet Components\r\nexport * from './bottom-sheet';\r\n\r\n// Mobile Lightbox Components\r\nexport * from './lightbox';\r\n\r\n// Mobile Inline Photo Component\r\nexport * from './inline-photo';\r\n\r\n// Mobile Modal Service\r\nexport * from './modal';\r\n\r\n// Mobile Post Detail Modal\r\nexport * from './post-detail-modal';\r\n\r\n// Mobile Handbook Components\r\nexport * from './handbook-folder';\r\n\r\n\r\n// Shared directives\r\nexport * from './shared';","import { Injectable, signal } from '@angular/core';\r\n\r\n/**\r\n * User service for managing current user data globally\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class UserService {\r\n // User avatar configuration\r\n private _avatarInitials = signal('LM');\r\n private _avatarType = signal<'initials' | 'photo' | 'icon'>('initials');\r\n private _avatarSrc = signal('');\r\n \r\n // Readonly computed values\r\n readonly avatarInitials = this._avatarInitials.asReadonly();\r\n readonly avatarType = this._avatarType.asReadonly();\r\n readonly avatarSrc = this._avatarSrc.asReadonly();\r\n \r\n /**\r\n * Update avatar configuration\r\n */\r\n setAvatarInitials(initials: string) {\r\n this._avatarInitials.set(initials);\r\n }\r\n \r\n setAvatarType(type: 'initials' | 'photo' | 'icon') {\r\n this._avatarType.set(type);\r\n }\r\n \r\n setAvatarSrc(src: string) {\r\n this._avatarSrc.set(src);\r\n }\r\n}\r\n\r\n","import { Component, signal, computed } from '@angular/core';\r\nimport { Router, ActivatedRoute } from '@angular/router';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileContentComponent } from '../components/content';\r\nimport { DsMobileInteractiveListItemPostComponent, PostPdfAttachmentComponent } from '../components/interactive-list-item-post';\r\nimport { \r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../components/interactive-list-item-post';\r\nimport { DsMobilePostComposerComponent } from '../components/post-composer';\r\nimport { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';\r\nimport { DsMobilePostCreateBottomSheetComponent } from '../components/bottom-sheet/ds-mobile-post-create-bottom-sheet';\r\nimport { DsMobilePostActionsBottomSheetComponent, PostActionResult } from '../components/bottom-sheet';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../components/lightbox';\r\nimport { DsMobilePostDetailModalService } from '../components/post-detail-modal';\r\nimport { DsMobileInlinePhotoComponent } from '../components/inline-photo';\r\nimport { UserService } from '../services/user.service';\r\n\r\n@Component({\r\n selector: 'app-mobile-community-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileContentComponent,\r\n DsMobileInteractiveListItemPostComponent,\r\n DsMobilePostComposerComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n PostPdfAttachmentComponent,\r\n DsIconComponent,\r\n DsMobileInlinePhotoComponent\r\n ],\r\n styles: [`\r\n .post-feed {\r\n display: flex;\r\n flex-direction: column;\r\n max-width: 640px;\r\n }\r\n \r\n .post-list-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Remove custom dividers - now handled by ds-mobile-list-item */\r\n \r\n .pinned-posts-section {\r\n margin: -12px -12px 12px -12px;\r\n padding: 0 12px 12px 12px;\r\n box-shadow: var(--box-shadow-sm);\r\n border-radius: 16px;\r\n border: 1px solid var(--border-color-default);\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n /* Empty State */\r\n .community-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n margin-bottom: 24px;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Fællesskab\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <!-- Post Composer in header-expandable -->\r\n <ds-mobile-post-composer\r\n header-content\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n [avatarSrc]=\"userService.avatarSrc()\"\r\n (composerClick)=\"openPostCreator()\"\r\n />\r\n \r\n <ds-mobile-content>\r\n <div class=\"post-feed\">\r\n <!-- Pinned Posts Section -->\r\n <div class=\"pinned-posts-section\">\r\n <h2 class=\"section-headline\">\r\n <ds-icon name=\"remixPushpinFill\" size=\"16px\" color=\"primary\" />\r\n Fastgjorte opslag\r\n </h2>\r\n \r\n <!-- Pinned: Maintenance Announcement -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Karen Nielsen'\"\r\n [authorRole]=\"'Ejendomsadministrator'\"\r\n [timestamp]=\"'2d siden'\"\r\n [avatarInitials]=\"'KN'\"\r\n [showBadge]=\"true\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('4')\"\r\n (commentClick)=\"openPost('4', true)\"\r\n (longPress)=\"handlePostLongPress('4', false)\">\r\n \r\n <post-content>\r\n <post-text>📢 Påmindelse: Bygningsvedligeholdelse planlagt til denne lørdag fra kl. 9 til 14. Vandet vil være midlertidigt lukket. Vær venlig at planlægge derefter!</post-text>\r\n \r\n <post-attachments>\r\n <post-pdf-attachment\r\n [fileName]=\"'Husregler.pdf'\"\r\n [fileSize]=\"'245 KB'\"\r\n (pdfClick)=\"openHouseRulesPdf()\">\r\n </post-pdf-attachment>\r\n </post-attachments>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"89\" />\r\n <action-comment [count]=\"67\" (commentClick)=\"openPost('4', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n </div>\r\n \r\n <!-- All Posts Section -->\r\n <h2 class=\"section-headline\">Alle opslag</h2>\r\n \r\n @if (hasAnyPosts()) {\r\n <div class=\"post-list-wrapper\">\r\n <!-- User Created Posts -->\r\n @for (post of userPosts(); track $index) {\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"post.authorName\"\r\n [authorRole]=\"post.authorRole\"\r\n [timestamp]=\"post.timestamp\"\r\n [avatarType]=\"post.avatarType\"\r\n [avatarSrc]=\"post.avatarSrc\"\r\n [avatarInitials]=\"post.avatarInitials\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openUserPost($index)\"\r\n (commentClick)=\"openUserPost($index, true)\"\r\n (longPress)=\"handlePostLongPress($index, post.authorRole === 'Dig')\">\r\n \r\n <post-content>\r\n @if (post.content) {\r\n <post-text>{{ post.content }}</post-text>\r\n }\r\n @if (post.imageSrc) {\r\n <post-media>\r\n <img \r\n [src]=\"post.imageSrc\" \r\n [alt]=\"post.imageAlt || 'Posted image'\" \r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox(post.imageSrc, post.imageAlt || 'Posted image', post.content, $event)\"\r\n />\r\n </post-media>\r\n }\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"post.likeCount\" [active]=\"post.isLiked\" />\r\n <action-comment [count]=\"post.commentCount\" (commentClick)=\"openUserPost($index, true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n }\r\n \r\n <!-- Post 1: Text only -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Anders Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarType]=\"'photo'\"\r\n [avatarSrc]=\"'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('1')\"\r\n (commentClick)=\"openPost('1', true)\"\r\n (longPress)=\"handlePostLongPress('1', false)\">\r\n \r\n <post-content>\r\n <post-text>Lige flyttet ind i min nye lejlighed! Udlejeren var super hjælpsom gennem hele processen. Virkelig begejstret for at være en del af dette fællesskab! 🏠</post-text>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"42\" />\r\n <action-comment [count]=\"12\" (commentClick)=\"openPost('1', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 2: With multiple images (grid layout) -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Sophie Andersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'4t siden'\"\r\n [avatarInitials]=\"'SA'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('2')\"\r\n (commentClick)=\"openPost('2', true)\"\r\n (longPress)=\"handlePostLongPress('2', false)\">\r\n \r\n <post-content>\r\n <post-text>Jeg har taget nogle billeder af vores smukke ejendom i løbet af det sidste par måneder. Fra altanudsigten om morgenen til den nye trappe og fællesområderne. Elsker virkelig at bo her! 🏡✨</post-text>\r\n <ds-mobile-inline-photo\r\n [images]=\"[\r\n '/Assets/Dummy-photos/balcony-view.jpg',\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/yard.jpg'\r\n ]\"\r\n [author]=\"{\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n avatarType: 'initials',\r\n timestamp: '4t siden'\r\n }\"\r\n />\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [active]=\"true\" [count]=\"156\" />\r\n <action-comment [count]=\"34\" (commentClick)=\"openPost('2', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 3: Question -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Thomas Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1d siden'\"\r\n [avatarType]=\"'photo'\"\r\n [avatarSrc]=\"'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('3')\"\r\n (commentClick)=\"openPost('3', true)\"\r\n (longPress)=\"handlePostLongPress('3', false)\">\r\n \r\n <post-content>\r\n <post-text>Kender nogen et fælles fitnesscenter i nærheden? Leder efter anbefalinger til gode træningscentre i området. 🏋️</post-text>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"23\" />\r\n <action-comment [count]=\"45\" (commentClick)=\"openPost('3', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 3.5: Property Manager showcase with 6+ photos -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Karen Nielsen'\"\r\n [authorRole]=\"'Ejendomsadministrator'\"\r\n [timestamp]=\"'2d siden'\"\r\n [avatarInitials]=\"'KN'\"\r\n [showBadge]=\"true\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('3.5')\"\r\n (commentClick)=\"openPost('3.5', true)\"\r\n (longPress)=\"handlePostLongPress('3.5', false)\">\r\n \r\n <post-content>\r\n <post-text>Her er et kig på vores nyligt renoverede fællesområder! Vi har opgraderet postkasserne, trappeafsatsen og gårdområdet. Der er også blevet ansat en ny vicevært. Glæd dig over forbedringerne! 🏢✨</post-text>\r\n <ds-mobile-inline-photo\r\n [images]=\"[\r\n '/Assets/Dummy-photos/mailboxes.jpg',\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/yard.jpg',\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/balcony-view.jpg',\r\n '/Assets/Dummy-photos/handyman.jpg'\r\n ]\"\r\n [author]=\"{\r\n name: 'Karen Nielsen',\r\n role: 'Ejendomsadministrator',\r\n avatarInitials: 'KN',\r\n avatarType: 'initials',\r\n timestamp: '2d siden'\r\n }\"\r\n [maxVisible]=\"5\"\r\n />\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"234\" />\r\n <action-comment [count]=\"89\" (commentClick)=\"openPost('3.5', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 5: Event -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Emma Petersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3d siden'\"\r\n [avatarType]=\"'photo'\"\r\n [avatarSrc]=\"'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('5')\"\r\n (commentClick)=\"openPost('5', true)\"\r\n (longPress)=\"handlePostLongPress('5', false)\">\r\n \r\n <post-content>\r\n <post-text>Arrangerer en fælles BBQ næste weekend! Alle er inviteret. Tag din yndlingsret med til at dele. Lad os lære hinanden bedre at kende! 🍔🌭</post-text>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [active]=\"true\" [count]=\"124\" />\r\n <action-comment [count]=\"89\" (commentClick)=\"openPost('5', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n </div>\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"community-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"Ingen opslag endnu\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">Ingen opslag endnu</h3>\r\n <p class=\"empty-state-description\">Vær den første til at dele noget med dit fællesskab</p>\r\n </div>\r\n }\r\n </div>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileCommunityPageComponent {\r\n // Store user-created posts\r\n userPosts = signal<any[]>([\r\n {\r\n id: 'user-post-1',\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: '5m siden',\r\n avatarType: 'initials' as 'photo' | 'initials' | 'icon',\r\n avatarInitials: 'LM',\r\n content: 'Dette er mit første opslag! Ser frem til at forbinde med alle i bygningen. 🏠',\r\n isLiked: false,\r\n likeCount: 3,\r\n commentCount: 1\r\n }\r\n ]);\r\n \r\n // Flag to control whether static demo posts are shown\r\n // Set to false to see the empty state\r\n showStaticPosts = signal(true);\r\n \r\n // Computed to check if there are any posts to display\r\n hasAnyPosts = computed(() => {\r\n return this.userPosts().length > 0 || this.showStaticPosts();\r\n });\r\n \r\n constructor(\r\n private router: Router,\r\n private route: ActivatedRoute,\r\n private bottomSheet: DsMobileBottomSheetService,\r\n private lightbox: DsMobileLightboxService,\r\n private postModal: DsMobilePostDetailModalService,\r\n public userService: UserService\r\n ) {}\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n /**\r\n * Open post detail modal\r\n * This provides a better UX than route navigation:\r\n * - Maintains scroll position\r\n * - Native iOS-style modal feel\r\n * - Proper close button that works\r\n */\r\n async openPost(postId: string, focusComment: boolean = false): Promise<void> {\r\n console.log('[Community] ===== openPost called =====', postId, 'Focus comment:', focusComment);\r\n \r\n // Map post ID to post data (in real app, fetch from service)\r\n const postDataMap: Record<string, any> = {\r\n '1': {\r\n postId: '1',\r\n authorName: 'Anders Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '2t siden',\r\n avatarType: 'photo' as const,\r\n avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face',\r\n content: 'Lige flyttet ind i min nye lejlighed! Udlejeren var super hjælpsom gennem hele processen. Virkelig begejstret for at være en del af dette fællesskab! 🏠',\r\n isLiked: false,\r\n likeCount: 42,\r\n commentCount: 12,\r\n comments: [\r\n {\r\n authorName: 'Mette Larsen',\r\n authorRole: 'Lejer',\r\n timestamp: '1t siden',\r\n avatarInitials: 'ML',\r\n content: 'Velkommen til fællesskabet!',\r\n likeCount: 5,\r\n isOwnComment: false\r\n },\r\n {\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarInitials: 'LM',\r\n content: 'Vxhknbh',\r\n likeCount: 0,\r\n isOwnComment: true\r\n }\r\n ]\r\n },\r\n '2': {\r\n postId: '2',\r\n authorName: 'Sophie Andersen',\r\n authorRole: 'Lejer',\r\n timestamp: '4t siden',\r\n avatarInitials: 'SA',\r\n content: 'Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️',\r\n imageSrc: '/Assets/Dummy-photos/balcony-view.jpg',\r\n imageAlt: 'Altanudsigt',\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34,\r\n comments: [\r\n {\r\n authorName: 'Anders Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '3t siden',\r\n avatarInitials: 'AJ',\r\n content: 'Wow, den udsigt er fantastisk! Hvilken etage er du på?',\r\n likeCount: 12,\r\n isOwnComment: false\r\n },\r\n {\r\n authorName: 'Thomas Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '3t siden',\r\n avatarInitials: 'TH',\r\n content: 'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆',\r\n isLiked: true,\r\n likeCount: 8,\r\n isOwnComment: false\r\n },\r\n {\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarInitials: 'LM',\r\n content: 'Vxhknbh',\r\n likeCount: 0,\r\n isOwnComment: true\r\n }\r\n ]\r\n },\r\n '3': {\r\n postId: '3',\r\n authorName: 'Thomas Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '1d siden',\r\n avatarType: 'photo' as const,\r\n avatarSrc: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face',\r\n content: 'Kender nogen et fælles fitnesscenter i nærheden? Leder efter anbefalinger til gode træningscentre i området. 🏋️',\r\n isLiked: false,\r\n likeCount: 23,\r\n commentCount: 45,\r\n comments: []\r\n },\r\n '4': {\r\n postId: '4',\r\n authorName: 'Karen Nielsen',\r\n authorRole: 'Ejendomsadministrator',\r\n timestamp: '2d siden',\r\n avatarInitials: 'KN',\r\n content: '📢 Påmindelse: Bygningsvedligeholdelse planlagt til denne lørdag fra kl. 9 til 14. Vandet vil være midlertidigt lukket. Vær venlig at planlægge derefter!',\r\n isLiked: false,\r\n likeCount: 89,\r\n commentCount: 67,\r\n comments: []\r\n },\r\n '5': {\r\n postId: '5',\r\n authorName: 'Emma Petersen',\r\n authorRole: 'Lejer',\r\n timestamp: '3d siden',\r\n avatarType: 'photo' as const,\r\n avatarSrc: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face',\r\n content: 'Arrangerer en fælles BBQ næste weekend! Alle er inviteret. Tag din yndlingsret med til at dele. Lad os lære hinanden bedre at kende! 🍔🌭',\r\n isLiked: true,\r\n likeCount: 124,\r\n commentCount: 89,\r\n comments: []\r\n }\r\n };\r\n\r\n const postData = postDataMap[postId];\r\n \r\n if (postData) {\r\n // Add focusComment flag to postData\r\n await this.postModal.open({ ...postData, focusComment });\r\n }\r\n }\r\n \r\n /**\r\n * Open user-created post detail modal\r\n */\r\n async openUserPost(index: number, focusComment: boolean = false): Promise<void> {\r\n const posts = this.userPosts();\r\n const post = posts[index];\r\n \r\n if (post) {\r\n console.log('[Community] Opening user post modal:', index, 'Focus comment:', focusComment);\r\n \r\n // Convert user post to modal format with empty comments array\r\n const postData = {\r\n ...post,\r\n postId: `user-${index}`,\r\n comments: [] // User posts don't have comments yet\r\n };\r\n \r\n await this.postModal.open({ ...postData, focusComment });\r\n }\r\n }\r\n \r\n async openPostCreator(): Promise<void> {\r\n // Open the post creator as a bottom sheet modal\r\n // Using 95% initial height to maximize keyboard auto-open chances\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobilePostCreateBottomSheetComponent,\r\n componentProps: {\r\n // This helps the component know it should auto-focus\r\n autoFocus: true\r\n },\r\n breakpoints: [0, 0.95, 1],\r\n initialBreakpoint: 0.95,\r\n handle: true\r\n });\r\n \r\n // Handle the result when the sheet is dismissed\r\n const result = await sheet.onWillDismiss();\r\n if (result.role === 'post' && result.data) {\r\n console.log('New post created:', result.data);\r\n \r\n // Create a new post object\r\n const newPost = {\r\n id: `user-post-${Date.now()}`, // Generate unique ID\r\n authorName: 'Lars Mikkelsen', // Current user name\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarType: this.userService.avatarType() as 'photo' | 'initials' | 'icon',\r\n avatarSrc: this.userService.avatarSrc(),\r\n avatarInitials: this.userService.avatarInitials(),\r\n content: result.data.content,\r\n imageSrc: result.data.images && result.data.images.length > 0 ? result.data.images[0] : undefined,\r\n imageAlt: result.data.images && result.data.images.length > 0 ? 'Slået billede op' : undefined,\r\n isLiked: false,\r\n likeCount: 0,\r\n commentCount: 0\r\n };\r\n \r\n // Add to the beginning of the posts array\r\n this.userPosts.update(posts => [newPost, ...posts]);\r\n }\r\n }\r\n \r\n /**\r\n * Open an image in the lightbox viewer\r\n * Prevents the post click event from firing\r\n */\r\n async openImageLightbox(imageSrc: string, title: string, description: string, event: Event): Promise<void> {\r\n console.log('[Community] Opening lightbox for image:', imageSrc);\r\n \r\n // Prevent the post card click event from firing\r\n event.stopPropagation();\r\n \r\n const authorMeta: LightboxAuthor = {\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n timestamp: '4t siden'\r\n };\r\n \r\n // Open the lightbox with the image\r\n await this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: imageSrc,\r\n alt: title,\r\n title: title,\r\n description: description,\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false, // Single image, no need for controls\r\n showInfo: true\r\n });\r\n }\r\n\r\n async openHouseRulesPdf(): Promise<void> {\r\n console.log('[Community] Opening House Rules PDF');\r\n \r\n // Author metadata\r\n const authorMeta: LightboxAuthor = {\r\n name: 'Karen Nielsen',\r\n role: 'Ejendomsadministrator',\r\n avatarInitials: 'KN',\r\n timestamp: '2d siden'\r\n };\r\n \r\n // Open the PDF lightbox\r\n // Use absolute path for production deployment (Vercel, etc.)\r\n await this.lightbox.openPdf({\r\n pdf: {\r\n type: 'pdf',\r\n src: '/Assets/House_Rules.pdf', // Capital A to match public/Assets folder structure\r\n title: 'House Rules',\r\n description: 'Building regulations and community guidelines',\r\n fileSize: 250880, // 245 KB in bytes\r\n pageCount: 8\r\n },\r\n author: authorMeta\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a post to show action sheet\r\n */\r\n async handlePostLongPress(postIdOrIndex: string | number, isOwnPost: boolean): Promise<void> {\r\n console.log('[Community] Post long pressed:', postIdOrIndex, 'isOwn:', isOwnPost);\r\n \r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobilePostActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnPost\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as PostActionResult).action;\r\n \r\n switch (action) {\r\n case 'edit':\r\n console.log('Edit post:', postIdOrIndex);\r\n // Open the post create bottom sheet in edit mode\r\n let postContent = '';\r\n let postId = '';\r\n \r\n // Get post content based on postIdOrIndex\r\n if (typeof postIdOrIndex === 'number') {\r\n const post = this.userPosts()[postIdOrIndex];\r\n if (post) {\r\n postContent = post.content || '';\r\n postId = post.id || postIdOrIndex.toString();\r\n }\r\n } else {\r\n // For static posts, we'll need to determine content\r\n // For now, use a placeholder\r\n postId = postIdOrIndex.toString();\r\n postContent = 'Edit this post...';\r\n }\r\n \r\n // Open the bottom sheet in edit mode\r\n const editSheet = await this.bottomSheet.create({\r\n component: DsMobilePostCreateBottomSheetComponent,\r\n componentProps: {\r\n autoFocus: true,\r\n isEditMode: true,\r\n postId: postId,\r\n initialContent: postContent\r\n },\r\n breakpoints: [0, 0.95, 1],\r\n initialBreakpoint: 0.95,\r\n handle: true,\r\n backdropBlur: true,\r\n backdropOpacity: 0.6\r\n });\r\n \r\n // Handle the result when the sheet is dismissed\r\n const editResult = await editSheet.onWillDismiss();\r\n if (editResult.role === 'post' && editResult.data) {\r\n console.log('Post updated:', editResult.data);\r\n \r\n // Update the post in the array\r\n if (typeof postIdOrIndex === 'number') {\r\n const currentPosts = this.userPosts();\r\n const updatedPosts = currentPosts.map((post, index) => \r\n index === postIdOrIndex \r\n ? { ...post, content: editResult.data.content, timestamp: 'Just now' }\r\n : post\r\n );\r\n this.userPosts.set(updatedPosts);\r\n }\r\n }\r\n break;\r\n case 'delete':\r\n console.log('Delete post:', postIdOrIndex);\r\n if (confirm('Er du sikker på, at du vil slette dette opslag?')) {\r\n // If it's a user post (number index), remove it from the array\r\n if (typeof postIdOrIndex === 'number') {\r\n const currentPosts = this.userPosts();\r\n const updatedPosts = currentPosts.filter((_, index) => index !== postIdOrIndex);\r\n this.userPosts.set(updatedPosts);\r\n }\r\n // Otherwise it's a static post, just show confirmation\r\n else {\r\n alert('Opslag slettet!');\r\n }\r\n }\r\n break;\r\n case 'like':\r\n console.log('Like post:', postIdOrIndex);\r\n // Toggle like - in a real app, this would call an API\r\n alert('Opslag liket!');\r\n break;\r\n case 'reply':\r\n console.log('Reply to post:', postIdOrIndex);\r\n // Open the post detail modal with comment input focused\r\n if (typeof postIdOrIndex === 'number') {\r\n await this.openUserPost(postIdOrIndex, true);\r\n } else {\r\n await this.openPost(postIdOrIndex, true);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Component } from '@angular/core';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { \r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent\r\n} from '../components/content';\r\nimport { DsMobileHandbookFolderComponent } from '../components/handbook-folder';\r\nimport { UserService } from '../services/user.service';\r\nimport { HandbookItem } from '../components/handbook-detail-modal/ds-mobile-handbook-detail-modal';\r\n\r\n@Component({\r\n selector: 'app-mobile-handbook-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent,\r\n DsMobileHandbookFolderComponent\r\n ],\r\n styles: [`\r\n .folders-grid {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 20px;\r\n justify-items: center;\r\n }\r\n\r\n /* 3 columns at tablet breakpoint (md: 768px) and above\r\n Content area at this breakpoint is ~864px max */\r\n @media (min-width: 768px) {\r\n .folders-grid {\r\n grid-template-columns: repeat(3, 1fr);\r\n }\r\n }\r\n \r\n ds-mobile-handbook-folder {\r\n width: 100%;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Håndbog\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <ds-mobile-content>\r\n <ds-mobile-content-section>\r\n <div class=\"folders-grid\">\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'pink'\"\r\n [iconName]=\"'remixLightbulbLine'\"\r\n [itemCount]=\"8\"\r\n [label]=\"'Forsyninger'\"\r\n [items]=\"utilitiesItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'success'\"\r\n [iconName]=\"'remixKey2Line'\"\r\n [itemCount]=\"4\"\r\n [label]=\"'Sikkerhedsudstyr'\"\r\n [items]=\"sikkerhedsudstyrItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'blue'\"\r\n [iconName]=\"'remixFileList3Line'\"\r\n [itemCount]=\"8\"\r\n [label]=\"'Servicekontrakter'\"\r\n [items]=\"serviceContractsItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'warning'\"\r\n [iconName]=\"'remixToolsLine'\"\r\n [itemCount]=\"5\"\r\n [label]=\"'Udstyr'\"\r\n [items]=\"equipmentItems\">\r\n </ds-mobile-handbook-folder>\r\n </div>\r\n </ds-mobile-content-section>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileHandbookPageComponent {\r\n // Utilities folder data\r\n utilitiesItems: HandbookItem[] = [\r\n {\r\n title: 'El',\r\n description: 'Hovedeltavle placeret i kælderrum B-12. Nødafbryderknap er ved hovedindgangen. Alle kredsløb er mærket.',\r\n contacts: [\r\n { name: 'ElektroTek ApS', initials: 'E', contactPerson: 'Lars Nielsen', phoneNumber: '+45 23 45 67 89' }\r\n ]\r\n },\r\n {\r\n title: 'Elektrisk diagram',\r\n description: 'Komplet diagram over bygningens elektriske installation med alle kredsløb og afbrydere.',\r\n attachments: [\r\n { name: 'Elektrisk_Diagram.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Vandforsyning',\r\n description: 'Hovedvandhane er placeret i kælderens tekniske rum. Individuelle lejlighedsafspærringer er i gangpanelerne. Vandtryk overvåges automatisk.',\r\n contacts: [\r\n { name: 'VVS Hansen', initials: 'V', contactPerson: 'Peter Hansen', phoneNumber: '+45 34 56 78 90' }\r\n ]\r\n },\r\n {\r\n title: 'Varmesystem',\r\n description: 'Fjernvarmetilslutning i kælder. Termostater i hver enhed kan justeres individuelt. Systemet vedligeholdes kvartalsvis af certificerede teknikere.',\r\n contacts: [\r\n { name: 'Varme Service A/S', initials: 'V', contactPerson: 'Maria Jensen', phoneNumber: '+45 45 67 89 01' }\r\n ]\r\n },\r\n {\r\n title: 'Varmeanlæg dokumentation',\r\n description: 'Teknisk dokumentation og vedligeholdelseshistorik for bygningens varmesystem.',\r\n attachments: [\r\n { name: 'Varmeplan.pdf', type: 'pdf' },\r\n { name: 'Vedligeholdelseslog.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Internet & TV',\r\n description: 'Fiberforbindelse i bygningen. Distributionspanel er i stueetageteknisk rum. Hver lejlighed har ethernet-stik i stue og soveværelser.',\r\n contacts: [\r\n { name: 'TeleCom Solutions', initials: 'T', contactPerson: 'Anders Petersen', phoneNumber: '+45 56 78 90 12' }\r\n ]\r\n },\r\n {\r\n title: 'Netværksopsætning guide',\r\n attachments: [\r\n { name: 'Netværksopsætning.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Affaldshåndtering',\r\n description: 'Affaldssorteringsstation placeret i gården. Afhentninger: Dagrenovation (man/tor), Genbrug (ons), Organisk (tir/fre). Storskrald kræver booking.',\r\n attachments: [\r\n { name: 'Affaldsretningslinjer.pdf', type: 'pdf' }\r\n ]\r\n }\r\n ];\r\n\r\n // Safety Equipment folder data\r\n sikkerhedsudstyrItems: HandbookItem[] = [\r\n {\r\n title: 'Fælles områder og sikkerhed',\r\n description: 'Trappeopgange med nødbelysning og brandsikre døre. Postkasser placeret i indgangspartiet. Hold altid flugtveje fri.',\r\n images: [\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/mailboxes.jpg'\r\n ]\r\n },\r\n {\r\n title: 'Hjertestarter (AED)',\r\n description: 'Automatisk hjertestarter placeret i stueetagen ved hovedindgangen. Tilgængelig 24/7. Ingen særlig uddannelse kræves - enheden guider dig gennem processen.',\r\n contacts: [\r\n { name: 'MediTech Service', initials: 'M', contactPerson: 'John Mortensen', phoneNumber: '+45 12 34 56 78' }\r\n ]\r\n },\r\n {\r\n title: 'Brandslukningsudstyr',\r\n description: 'Brandslukkere placeret på hver etage. Eftersyn udføres årligt. Brandalarm aktiveres automatisk ved røg.',\r\n attachments: [\r\n { name: 'Brandplan.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Alarmsystem',\r\n description: 'Adgangskontrol med kodesystem ved alle indgange. Kode ændres kvartalsvis. Ved indbrud kontakt straks politiet og ejendomsadministrationen.',\r\n contacts: [\r\n { name: 'SecureHome A/S', initials: 'S', contactPerson: 'Henrik Johansen', phoneNumber: '+45 98 76 54 32' }\r\n ]\r\n }\r\n ];\r\n\r\n // Service Contracts folder data\r\n serviceContractsItems: HandbookItem[] = [\r\n {\r\n title: 'Rengøringsservice',\r\n description: 'Ugentlig rengøring af fællesarealer inklusiv indgangshal, trapper og elevatorer. Hovedrengøring kvartalsvis. Service leveres mandag-fredag, 6:00-9:00.',\r\n contacts: [\r\n { name: 'CleanCo Denmark', initials: 'C', contactPerson: 'Anne Kristensen', phoneNumber: '+45 89 01 23 45' }\r\n ]\r\n },\r\n {\r\n title: 'Rengøringskontrakt',\r\n attachments: [\r\n { name: 'Rengøringskontrakt_2024.pdf', type: 'pdf' },\r\n { name: 'Rengøringsplan.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Udendørs arealer',\r\n description: 'Fælles grønne områder med bede, siddepladser og terrasse. Beboere må frit benytte området. Respektér planterne og hold området pænt.',\r\n images: [\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/yard.jpg'\r\n ]\r\n },\r\n {\r\n title: 'Havevedligeholdelse',\r\n description: 'Professionel havepleje inklusiv plæneklipning, hækklipning og blomsterbedvedligeholdelse. Vintersnefjerning inkluderet.',\r\n contacts: [\r\n { name: 'Green Gardens ApS', initials: 'G', contactPerson: 'Michael Olsen', phoneNumber: '+45 90 12 34 56' }\r\n ]\r\n },\r\n {\r\n title: 'Haveserviceaftale',\r\n attachments: [\r\n { name: 'Haveserviceaftale.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Vinduespolering',\r\n description: 'Professionel vinduespoleringsservice for alle udvendige vinduer to gange årligt - forår og efterår.',\r\n contacts: [\r\n { name: 'Crystal Clear Windows', initials: 'C', contactPerson: 'Lene Schmidt', phoneNumber: '+45 01 23 45 67' }\r\n ]\r\n },\r\n {\r\n title: 'Sikkerhedsservice',\r\n description: '24/7 overvågningsservice med alarmrespons. Direkte forbindelse til politi og brandvæsen.',\r\n contacts: [\r\n { name: 'SecureHome A/S', initials: 'S', contactPerson: 'Henrik Johansen', phoneNumber: '+45 12 34 56 78' }\r\n ]\r\n },\r\n {\r\n title: 'Sikkerhedskontrakt og procedurer',\r\n attachments: [\r\n { name: 'Sikkerhedskontrakt.pdf', type: 'pdf' },\r\n { name: 'Nødprocedurer.pdf', type: 'pdf' }\r\n ]\r\n }\r\n ];\r\n\r\n // Equipment folder data\r\n equipmentItems: HandbookItem[] = [\r\n {\r\n title: 'Balkon udsigt',\r\n description: 'Eksempel på udsigt fra øverste etagers balkoner. Flere lejligheder har privat altan med fantastisk udsyn.',\r\n images: [\r\n '/Assets/Dummy-photos/balcony-view.jpg'\r\n ]\r\n },\r\n {\r\n title: 'Vaskerum',\r\n description: 'Fælles vaskerum med 4 vaskemaskiner og 4 tørretumblere. Bookingsystem tilgængeligt via beboerportal. Maskiner accepterer betalingskort. Åbningstider: 7:00-22:00.',\r\n contacts: [\r\n { name: 'WashTech Service', initials: 'W', contactPerson: 'Kirsten Berg', phoneNumber: '+45 34 56 78 90' }\r\n ]\r\n },\r\n {\r\n title: 'Vaskeri instruktioner',\r\n attachments: [\r\n { name: 'Vaskeinstruktioner.pdf', type: 'pdf' },\r\n { name: 'Bookingguide.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Vedligeholdelse og reparationer',\r\n description: 'Ved behov for reparationer eller vedligeholdelse i din lejlighed, kontakt vores hausmeister. Akutte problemer håndteres samme dag.',\r\n images: [\r\n '/Assets/Dummy-photos/handyman.jpg'\r\n ],\r\n contacts: [\r\n { name: 'Hausmeister Service', initials: 'H', contactPerson: 'Erik Sørensen', phoneNumber: '+45 56 78 90 12' }\r\n ]\r\n },\r\n {\r\n title: 'Værktøjsudlån',\r\n description: 'Basis håndværktøj tilgængeligt til beboerbrug. Kvittér for værktøj ved receptionen. Returnér inden for 48 timer.',\r\n attachments: [\r\n { name: 'Værktøjsliste.pdf', type: 'pdf' },\r\n { name: 'Udlånspolitik.pdf', type: 'pdf' }\r\n ]\r\n }\r\n ];\r\n \r\n constructor(public userService: UserService) {}\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n}\r\n\r\n","import { Component } from '@angular/core';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { \r\n DsMobileHeaderContentComponent,\r\n DsMobileHeaderContentTileComponent,\r\n TileIconComponent,\r\n TileContentComponent,\r\n TileLabelComponent,\r\n TileValueComponent\r\n} from '../components/header-content';\r\nimport { \r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent\r\n} from '../components/content';\r\nimport { UserService } from '../services/user.service';\r\n\r\n@Component({\r\n selector: 'app-home-page',\r\n standalone: true,\r\n imports: [\r\n DsIconComponent,\r\n DsMobilePageMainComponent,\r\n DsMobileHeaderContentComponent,\r\n DsMobileHeaderContentTileComponent,\r\n TileIconComponent,\r\n TileContentComponent,\r\n TileLabelComponent,\r\n TileValueComponent,\r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent\r\n ],\r\n styles: [`\r\n /* Placeholder grey boxes for content */\r\n .grey-box {\r\n height: 120px;\r\n border-radius: 12px;\r\n background: var(--color-background-neutral-tertiary);\r\n flex: 1;\r\n }\r\n\r\n .grey-box.clickable {\r\n background: var(--color-background-brand);\r\n cursor: pointer;\r\n transition: transform var(--transition-duration-fast) var(--ease-smooth);\r\n }\r\n\r\n .grey-box.clickable:active {\r\n transform: scale(0.98);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Hjem\"\r\n headerTitle=\"Velkommen, Lars\"\r\n headerSubtitle=\"Din lejebolig på et øjeblik.\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <!-- Property info tiles in header -->\r\n <ds-mobile-header-content header-content>\r\n <ds-mobile-header-content-tile>\r\n <tile-icon>\r\n <ds-icon name=\"remixHome4Line\" size=\"20px\" color=\"#DFE4FF\" />\r\n </tile-icon>\r\n <tile-content>\r\n <tile-label>Areal</tile-label>\r\n <tile-value>120 m²</tile-value>\r\n </tile-content>\r\n </ds-mobile-header-content-tile>\r\n\r\n <ds-mobile-header-content-tile>\r\n <tile-icon>\r\n <ds-icon name=\"remixCollageLine\" size=\"20px\" color=\"#DFE4FF\" />\r\n </tile-icon>\r\n <tile-content>\r\n <tile-label>Værelser</tile-label>\r\n <tile-value>3 værelser</tile-value>\r\n </tile-content>\r\n </ds-mobile-header-content-tile>\r\n </ds-mobile-header-content>\r\n \r\n <!-- Main page content -->\r\n <ds-mobile-content>\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <!-- Purple box - clickable with brand background -->\r\n <content-row>\r\n <div class=\"grey-box clickable\" (click)=\"navigateToDetail()\"></div>\r\n </content-row>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"half\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"half\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"half\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileHomePageComponent {\r\n constructor(\r\n private navCtrl: NavController,\r\n public userService: UserService\r\n ) {\r\n console.log('MobileHomePageComponent constructor');\r\n }\r\n\r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n\r\n navigateToDetail(): void {\r\n // Navigation removed - home/detail page was deleted\r\n console.log('Navigate to detail (page removed)');\r\n }\r\n}\r\n\r\n","import { Animation } from '@ionic/angular';\r\nimport { createAnimation } from '@ionic/core';\r\n\r\n/**\r\n * Custom page transition - iOS-style push/pop\r\n * \r\n * FORWARD (navigating TO detail):\r\n * - Entering page (detail): slides in from RIGHT, z-index 10 (on top)\r\n * - Leaving page (list): slides LEFT slightly, z-index 9 (underneath)\r\n * \r\n * REVERSE (swipe back FROM detail):\r\n * - Entering page (list): slides in from LEFT, z-index 9 (underneath)\r\n * - Leaving page (detail): slides out to RIGHT, z-index 10 (on top)\r\n */\r\nexport const customPageTransition = (_: HTMLElement, opts: any): Animation => {\r\n const DURATION = 400;\r\n const isBackDirection = opts.direction === 'back';\r\n \r\n const rootTransition = createAnimation()\r\n .duration(opts.duration || DURATION)\r\n .easing('cubic-bezier(0.32,0.72,0,1)');\r\n\r\n // Entering page animation\r\n const enteringPage = createAnimation()\r\n .addElement(opts.enteringEl)\r\n .beforeRemoveClass('ion-page-invisible')\r\n .beforeStyles({\r\n 'z-index': isBackDirection ? '9' : '10',\r\n 'opacity': '1'\r\n })\r\n .fromTo('transform', \r\n isBackDirection ? 'translateX(-20%)' : 'translateX(100%)', \r\n 'translateX(0)'\r\n );\r\n\r\n // Leaving page animation\r\n const leavingPage = createAnimation()\r\n .addElement(opts.leavingEl)\r\n .beforeStyles({\r\n 'z-index': isBackDirection ? '10' : '9'\r\n })\r\n .fromTo('transform', \r\n 'translateX(0)', \r\n isBackDirection ? 'translateX(100%)' : 'translateX(-20%)'\r\n );\r\n\r\n rootTransition.addAnimation([enteringPage, leavingPage]);\r\n \r\n return rootTransition;\r\n};\r\n\r\n/**\r\n * Custom back transition - iOS style where page slides out to reveal page underneath\r\n * The entering page (inquiries) slides in from the LEFT underneath\r\n * The leaving page (detail) slides out to the RIGHT on top\r\n */\r\nexport const customBackTransition = (_: HTMLElement, opts: any): Animation => {\r\n const DURATION = 400;\r\n \r\n const rootTransition = createAnimation()\r\n .duration(opts.duration || DURATION)\r\n .easing('cubic-bezier(0.32,0.72,0,1)');\r\n\r\n // Entering page: underneath, sliding in from LEFT (-20% to 0)\r\n const enteringPage = createAnimation()\r\n .addElement(opts.enteringEl)\r\n .beforeRemoveClass('ion-page-invisible')\r\n .beforeStyles({\r\n 'z-index': '9',\r\n 'opacity': '1'\r\n })\r\n .fromTo('transform', 'translateX(-20%)', 'translateX(0)');\r\n\r\n // Leaving page: on top, sliding out to the RIGHT (0 to 100%)\r\n const leavingPage = createAnimation()\r\n .addElement(opts.leavingEl)\r\n .beforeStyles({\r\n 'z-index': '10',\r\n })\r\n .fromTo('transform', 'translateX(0)', 'translateX(100%)');\r\n\r\n rootTransition.addAnimation([enteringPage, leavingPage]);\r\n \r\n return rootTransition;\r\n};\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\nexport interface TabItem {\r\n id: string;\r\n label: string;\r\n badge?: number;\r\n}\r\n\r\n/**\r\n * DsMobileTabBarComponent\r\n * \r\n * Pill-style tab bar for filtering/switching views\r\n * Used in the purple header section of pages\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tab-bar\r\n * [tabs]=\"[\r\n * { id: 'all', label: 'All' },\r\n * { id: 'open', label: 'Open' },\r\n * { id: 'closed', label: 'Closed' }\r\n * ]\"\r\n * [activeTab]=\"'all'\"\r\n * (tabChange)=\"handleTabChange($event)\">\r\n * </ds-mobile-tab-bar>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tab-bar',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n .filter-tabs {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n flex-wrap: wrap;\r\n height: 40px;\r\n }\r\n \r\n .filter-tab {\r\n min-width: 48px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 0px 12px;\r\n height: 32px;\r\n border-radius: 20px;\r\n background: transparent;\r\n border: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n color: rgba(255, 255, 255, 0.6);\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n white-space: nowrap;\r\n }\r\n \r\n .filter-tab.active {\r\n background: var(--color-background-brand, #5d5fef);\r\n color: white;\r\n }\r\n \r\n .filter-tab:hover:not(.active) {\r\n background: rgba(255, 255, 255, 0.1);\r\n }\r\n \r\n .tab-badge {\r\n min-width: 24px;\r\n height: 16px;\r\n padding: 0 6px;\r\n border-radius: 10px;\r\n background: rgba(255, 255, 255, 0.2);\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 600;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n line-height: 1;\r\n }\r\n \r\n .filter-tab.active .tab-badge {\r\n background: rgba(255, 255, 255, 0.3);\r\n color: white;\r\n }\r\n `],\r\n template: `\r\n <div class=\"filter-tabs\">\r\n @for (tab of tabs(); track tab.id) {\r\n <button \r\n class=\"filter-tab\"\r\n [class.active]=\"activeTab() === tab.id\"\r\n (click)=\"handleTabClick(tab.id)\"\r\n [attr.aria-label]=\"tab.label\"\r\n [attr.aria-selected]=\"activeTab() === tab.id\">\r\n {{ tab.label }}\r\n @if (tab.badge && tab.badge > 0) {\r\n <span class=\"tab-badge\">{{ tab.badge }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsMobileTabBarComponent {\r\n /**\r\n * Array of tab items to display\r\n */\r\n tabs = input.required<TabItem[]>();\r\n \r\n /**\r\n * Currently active tab ID\r\n */\r\n activeTab = input.required<string>();\r\n \r\n /**\r\n * Emitted when a tab is clicked\r\n */\r\n tabChange = output<string>();\r\n \r\n handleTabClick(tabId: string): void {\r\n this.tabChange.emit(tabId);\r\n }\r\n}\r\n\r\n","import { Component, signal, computed, effect } from '@angular/core';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileContentComponent } from '../components/content';\r\nimport { DsMobileInteractiveListItemInquiryComponent } from '../components/interactive-list-item-inquiry';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { UserService } from '../services/user.service';\r\nimport { customPageTransition } from '../animations/page-transitions';\r\nimport { DsMobileTabBarComponent, type TabItem } from '../components/tab-bar';\r\n\r\ninterface Inquiry {\r\n id: string;\r\n title: string;\r\n description: string;\r\n status: 'open' | 'closed';\r\n timestamp: string;\r\n category: 'maintenance' | 'plumbing' | 'electrical' | 'heating' | 'security' | 'appliance' | 'other';\r\n}\r\n\r\n@Component({\r\n selector: 'app-mobile-inquiries-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileContentComponent,\r\n DsMobileInteractiveListItemInquiryComponent,\r\n DsIconComponent,\r\n DsMobileTabBarComponent\r\n ],\r\n host: {\r\n class: 'ion-page'\r\n },\r\n styles: [`\r\n .inquiries-container {\r\n display: flex;\r\n flex-direction: column;\r\n max-width: 640px;\r\n }\r\n \r\n .inquiry-list-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Remove custom dividers - now handled by ds-mobile-list-item */\r\n \r\n .empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n color: var(--color-text-primary);\r\n margin: 16px 0 8px 0;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n color: var(--color-text-secondary);\r\n margin: 0;\r\n }\r\n \r\n\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Henvendelser\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\">\r\n \r\n <!-- Filter tabs in header -->\r\n <div header-content>\r\n <ds-mobile-tab-bar\r\n [tabs]=\"tabItems\"\r\n [activeTab]=\"filterStatus()\"\r\n (tabChange)=\"setFilter($any($event))\">\r\n </ds-mobile-tab-bar>\r\n </div>\r\n \r\n <ds-mobile-content>\r\n <div class=\"inquiries-container\">\r\n @if (filteredInquiries().length > 0) {\r\n <div class=\"inquiry-list-wrapper\">\r\n @for (inquiry of filteredInquiries(); track inquiry.id; let idx = $index) {\r\n <ds-mobile-interactive-list-item-inquiry\r\n [title]=\"inquiry.title\"\r\n [description]=\"inquiry.description\"\r\n [status]=\"inquiry.status\"\r\n [timestamp]=\"inquiry.timestamp\"\r\n [iconName]=\"getInquiryIcon(inquiry.category)\"\r\n [clickable]=\"true\"\r\n [showChevron]=\"false\"\r\n (inquiryClick)=\"openInquiryDetail(inquiry.id)\"\r\n (longPress)=\"showInquiryActions(inquiry.id)\">\r\n </ds-mobile-interactive-list-item-inquiry>\r\n\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty state -->\r\n <div class=\"empty-state\">\r\n <ds-icon name=\"remixInboxLine\" size=\"48px\" color=\"tertiary\" />\r\n <h3 class=\"empty-state-title\">Ingen henvendelser endnu</h3>\r\n <p class=\"empty-state-description\">\r\n @if (filterStatus() === 'open') {\r\n Du har ingen åbne henvendelser\r\n } @else if (filterStatus() === 'closed') {\r\n Du har ingen lukkede henvendelser\r\n } @else {\r\n Du har ikke oprettet nogen henvendelser endnu\r\n }\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileInquiriesPageComponent {\r\n constructor(\r\n public userService: UserService,\r\n private navCtrl: NavController\r\n ) {}\r\n \r\n filterStatus = signal<'all' | 'open' | 'closed'>('all');\r\n \r\n tabItems: TabItem[] = [\r\n { id: 'all', label: 'Alle' },\r\n { id: 'open', label: 'Åben' },\r\n { id: 'closed', label: 'Lukket' }\r\n ];\r\n \r\n inquiries = signal<Inquiry[]>([\r\n {\r\n id: '1',\r\n title: 'Tørretumbler virker ikke',\r\n description: 'I de sidste tre dage har jeg oplevet vedvarende problemer med tørretumbleren. Den starter, men stopper efter få minutter.',\r\n status: 'open',\r\n timestamp: '12 dage siden',\r\n category: 'appliance'\r\n },\r\n {\r\n id: '2',\r\n title: 'Problem med vandtryk',\r\n description: 'Lavt vandtryk i badeværelseshåndvasken. Det er blevet gradvist værre i løbet af den sidste uge.',\r\n status: 'open',\r\n timestamp: '5 dage siden',\r\n category: 'plumbing'\r\n },\r\n {\r\n id: '3',\r\n title: 'Varme virker ikke ordentligt',\r\n description: 'Varmesystemet holder ikke den indstillede temperatur. Lejligheden er meget koldere, end den burde være.',\r\n status: 'closed',\r\n timestamp: '2 måneder siden',\r\n category: 'heating'\r\n }\r\n ]);\r\n \r\n // Computed signals that automatically update when dependencies change\r\n filteredInquiries = computed(() => {\r\n const all = this.inquiries();\r\n const status = this.filterStatus();\r\n \r\n if (status === 'all') {\r\n return all;\r\n } else if (status === 'open') {\r\n return all.filter(i => i.status === 'open');\r\n } else {\r\n return all.filter(i => i.status === 'closed');\r\n }\r\n });\r\n \r\n openInquiries = computed(() => {\r\n return this.inquiries().filter(i => i.status === 'open');\r\n });\r\n \r\n closedInquiries = computed(() => {\r\n return this.inquiries().filter(i => i.status === 'closed');\r\n });\r\n \r\n setFilter(status: 'all' | 'open' | 'closed'): void {\r\n this.filterStatus.set(status);\r\n }\r\n \r\n getInquiryIcon(category: string): string {\r\n return 'remixTodoLine';\r\n }\r\n \r\n openInquiryDetail(inquiryId: string): void {\r\n console.log('Opening inquiry:', inquiryId);\r\n // Navigate to inquiry detail page with custom transition (absolute path outside tabs for animations)\r\n this.navCtrl.navigateForward([`/inquiry-detail/${inquiryId}`], {\r\n animation: customPageTransition\r\n });\r\n }\r\n \r\n showInquiryActions(inquiryId: string): void {\r\n console.log('Showing actions for inquiry:', inquiryId);\r\n // Show bottom sheet with actions (edit, delete, etc.)\r\n }\r\n}\r\n\r\n","import { Component, input, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileListItemStaticComponent\r\n * \r\n * A read-only version of the interactive list item component.\r\n * Used for displaying static information without interaction.\r\n * \r\n * This component has the same structure as the interactive list item but without:\r\n * - Padding\r\n * - Rounded corners\r\n * - Hover states\r\n * - Click interactions\r\n * - Background fill (transparent)\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-list-item-static\r\n * [leadingSize]=\"'40px'\">\r\n * \r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n * \r\n * <div content-main>\r\n * <h3>Main Content</h3>\r\n * <p>Supporting text goes here...</p>\r\n * </div>\r\n * \r\n * <div content-trailing>\r\n * <span>Info</span>\r\n * </div>\r\n * </ds-mobile-list-item-static>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-list-item-static',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[style.--leading-size]': 'leadingSize()'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n background: transparent;\r\n padding: 0;\r\n gap: 12px;\r\n position: relative;\r\n --leading-size: 32px;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -10px;\r\n left: calc(var(--leading-size) + 12px);\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n .content-leading {\r\n flex-shrink: 0;\r\n width: var(--leading-size);\r\n min-height: var(--leading-size);\r\n height: auto;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n min-height: var(--leading-size);\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n align-items: flex-start;\r\n gap: 8px;\r\n }\r\n \r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-start;\r\n }\r\n `],\r\n template: `\r\n @if (hasLeadingContent()) {\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n }\r\n \r\n <div class=\"content-main\">\r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n \r\n @if (hasTrailingContent()) {\r\n <div class=\"content-trailing\">\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n }\r\n `\r\n})\r\nexport class DsMobileListItemStaticComponent {\r\n /**\r\n * CSS size value for the leading content area (e.g., '32px', '40px', '48px')\r\n * Defaults to '32px' for standard list item avatars\r\n */\r\n leadingSize = input<string>('32px');\r\n \r\n /**\r\n * Check if leading content slot has content\r\n */\r\n hasLeadingContent = computed(() => true); // Always render slot container for consistency\r\n \r\n /**\r\n * Check if trailing content slot has content\r\n */\r\n hasTrailingContent = computed(() => true); // Always render slot container for consistency\r\n}\r\n\r\n","import { Component, signal, computed, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NavController, Platform } from '@ionic/angular/standalone';\r\nimport { \r\n IonHeader, \r\n IonToolbar, \r\n IonTitle,\r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent \r\n} from '@ionic/angular/standalone';\r\nimport { DsIconComponent, DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileTabBarComponent, type TabItem } from '../components/tab-bar';\r\nimport { DsMobileListItemStaticComponent } from '../components/list-item-static';\r\nimport { DsMobileInteractiveListItemMessageComponent } from '../components/interactive-list-item-message';\r\nimport { UserService } from '../services/user.service';\r\nimport { MobilePageBase } from '../components/shared/mobile-page-base';\r\nimport { customBackTransition } from '../animations/page-transitions';\r\n\r\ninterface ActivityItem {\r\n id: string;\r\n type: 'assignment' | 'status_change' | 'creation';\r\n actor?: string;\r\n actorInitials?: string;\r\n title: string;\r\n description?: string;\r\n timestamp: string;\r\n date: string;\r\n iconName: string;\r\n iconBgColor?: string;\r\n}\r\n\r\ninterface MessageThread {\r\n id: string;\r\n senderName: string;\r\n senderAvatar: string;\r\n senderInitials: string;\r\n message: string;\r\n role: string;\r\n timestamp: string;\r\n unread: boolean;\r\n}\r\n\r\n@Component({\r\n selector: 'app-mobile-inquiry-detail-page',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsIconComponent,\r\n DsAvatarComponent,\r\n DsMobileTabBarComponent,\r\n DsMobileListItemStaticComponent,\r\n DsMobileInteractiveListItemMessageComponent\r\n ],\r\n host: {\r\n class: 'ion-page'\r\n },\r\n styleUrls: ['./inquiry-detail.example.css'],\r\n template: `\r\n <!-- Fixed header at top -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-detail\">\r\n <!-- Back Button -->\r\n <button class=\"back-button\" (click)=\"goBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftSLine\" size=\"24px\" color=\"white\" />\r\n </button>\r\n \r\n <!-- Title - fades in on scroll -->\r\n <ion-title class=\"header-detail__title\">{{ inquiryTitle }}</ion-title>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content with expandable header -->\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n <!-- Pull to refresh (only on native iOS/Android) -->\r\n @if (isNativePlatform()) {\r\n <ion-refresher \r\n slot=\"fixed\" \r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\" \r\n [pullMin]=\"80\" \r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"remixArrowDownS\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <!-- Expandable header section (purple background) -->\r\n <div class=\"header-expandable\">\r\n <div class=\"header-expandable-inner\">\r\n <div class=\"header-expandable__text\">\r\n <h1 class=\"header-expandable__title\">{{ inquiryTitle }}</h1>\r\n </div>\r\n \r\n <!-- Tabs in header -->\r\n <ds-mobile-tab-bar\r\n [tabs]=\"tabItems\"\r\n [activeTab]=\"activeTab()\"\r\n (tabChange)=\"setActiveTab($event)\">\r\n </ds-mobile-tab-bar>\r\n </div>\r\n </div>\r\n\r\n <!-- Content wrapper -->\r\n <div class=\"content-wrapper\">\r\n <div class=\"content-inner\">\r\n <!-- Activity Tab Content -->\r\n @if (activeTab() === 'activity') {\r\n <div class=\"activity-list\">\r\n @for (activity of activities; track activity.id) {\r\n <div class=\"activity-item\">\r\n @if (activity.actor) {\r\n <!-- Avatar with badge for actor activities -->\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [type]=\"'initials'\"\r\n [initials]=\"activity.actorInitials || ''\"\r\n size=\"md\" />\r\n \r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Icon wrapper for non-actor activities -->\r\n <div class=\"activity-icon-wrapper\">\r\n <ds-icon \r\n [name]=\"activity.iconName\"\r\n size=\"18px\"\r\n color=\"secondary\" />\r\n </div>\r\n }\r\n \r\n <div class=\"activity-content\">\r\n <p class=\"activity-title\">\r\n @if (activity.actor) {\r\n <span class=\"actor-name\">{{ activity.actor }}</span>\r\n <span class=\"activity-text\"> {{ activity.title }}</span>\r\n } @else {\r\n <span class=\"actor-name\">{{ activity.title }}</span>\r\n }\r\n </p>\r\n @if (activity.description) {\r\n <p class=\"activity-description\">{{ activity.description }}</p>\r\n }\r\n <div class=\"activity-timestamp\">\r\n <ds-icon name=\"remixCalendarLine\" size=\"12px\" color=\"--color-text-tertiary\" />\r\n <span>{{ activity.date }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Messages Tab Content -->\r\n @if (activeTab() === 'messages') {\r\n <div class=\"messages-list\">\r\n @for (message of messageThreads; track message.id) {\r\n <ds-mobile-interactive-list-item-message\r\n [senderName]=\"message.senderName\"\r\n [senderRole]=\"message.role\"\r\n [message]=\"message.message\"\r\n [avatarInitials]=\"message.senderInitials\"\r\n [unread]=\"message.unread\"\r\n (messageClick)=\"openMessage(message.id)\">\r\n </ds-mobile-interactive-list-item-message>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Details Tab Content -->\r\n @if (activeTab() === 'details') {\r\n <div class=\"details-list\">\r\n <!-- Assignee -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-avatar\r\n [size]=\"'sm'\"\r\n [type]=\"'initials'\"\r\n [initials]=\"'R'\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-label\">Sagsbehandler</div>\r\n <div class=\"detail-value\">Ricki Meihlen</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Technician -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-avatar\r\n [size]=\"'sm'\"\r\n [type]=\"'initials'\"\r\n [initials]=\"'M'\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-label\">Tekniker</div>\r\n <div class=\"detail-value\">Martin Smith</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Title -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-icon name=\"remixTextBlock\" size=\"20px\" color=\"tertiary\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-value\">{{ inquiryTitle }}</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Description -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-icon name=\"remixAlignLeft\" size=\"20px\" color=\"tertiary\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-value description-text\">\r\n I de sidste tre dage har vi oplevet vedvarende problemer med tørretumbleren i vores lejlighed. På trods af at vi følger betjeningsvejledningen, fejler maskinen konsekvent i at fuldføre sine tørrecyklusser.\r\n </div>\r\n <div class=\"detail-tag\">Husholdningsapparater</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Photos -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-icon name=\"remixCameraLine\" size=\"20px\" color=\"tertiary\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"photo-grid\">\r\n <button class=\"photo-add\">\r\n <ds-icon name=\"remixAddLine\" size=\"20px\" color=\"tertiary\" />\r\n </button>\r\n <!-- Placeholder photos -->\r\n <div class=\"photo-item\"></div>\r\n <div class=\"photo-item\"></div>\r\n <div class=\"photo-item\"></div>\r\n <div class=\"photo-item\"></div>\r\n </div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class MobileInquiryDetailPageComponent extends MobilePageBase implements AfterViewInit {\r\n @ViewChild(IonContent) ionContent?: IonContent;\r\n \r\n // Platform detection\r\n private platform = inject(Platform);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n \r\n inquiryTitle = 'Tørretumbler virker ikke';\r\n activeTab = signal<string>('activity');\r\n \r\n tabItems: TabItem[] = [\r\n { id: 'activity', label: 'Aktivitet' },\r\n { id: 'messages', label: 'Beskeder', badge: 0 },\r\n { id: 'details', label: 'Detaljer' }\r\n ];\r\n \r\n activities: ActivityItem[] = [\r\n {\r\n id: '1',\r\n type: 'assignment',\r\n actor: 'Martin Smith',\r\n actorInitials: 'MS',\r\n title: 'er blevet tildelt som din dedikerede tekniker.',\r\n timestamp: '2 dage siden',\r\n date: '28. feb 2025',\r\n iconName: 'remixUserAddLine'\r\n },\r\n {\r\n id: '2',\r\n type: 'assignment',\r\n actor: 'Ricki Meihlen',\r\n actorInitials: 'RM',\r\n title: 'er blevet tildelt til at håndtere din henvendelse.',\r\n timestamp: '8 dage siden',\r\n date: '22. feb 2025',\r\n iconName: 'remixUserLine'\r\n },\r\n {\r\n id: '3',\r\n type: 'creation',\r\n title: 'Henvendelse oprettet',\r\n timestamp: '8 dage siden',\r\n date: '22. feb 2025',\r\n iconName: 'remixAddCircleLine'\r\n }\r\n ];\r\n \r\n messageThreads: MessageThread[] = [\r\n {\r\n id: '1',\r\n senderName: 'Ove Hindborg',\r\n senderAvatar: '',\r\n senderInitials: 'OH',\r\n message: 'Dejligt at høre! Jeg venter på din teknikerbesøg tidsplan.',\r\n role: 'Sagsbehandler',\r\n timestamp: '2t siden',\r\n unread: true\r\n },\r\n {\r\n id: '2',\r\n senderName: 'Martin Smith',\r\n senderAvatar: '',\r\n senderInitials: 'MS',\r\n message: 'Dejligt at høre! Jeg venter på din teknikerbesøg tidsplan.',\r\n role: 'Tekniker',\r\n timestamp: '4t siden',\r\n unread: true\r\n }\r\n ];\r\n \r\n unreadMessagesCount = computed(() => {\r\n const count = this.messageThreads.filter(m => m.unread).length;\r\n // Update badge in tab items\r\n const messagesTab = this.tabItems.find(t => t.id === 'messages');\r\n if (messagesTab) {\r\n messagesTab.badge = count;\r\n }\r\n return count;\r\n });\r\n \r\n constructor(\r\n public userService: UserService,\r\n private navCtrl: NavController,\r\n private elementRef: ElementRef\r\n ) {\r\n super();\r\n // Trigger initial badge update\r\n this.unreadMessagesCount();\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial setup if needed\r\n }\r\n \r\n setActiveTab(tabId: string): void {\r\n this.activeTab.set(tabId);\r\n }\r\n \r\n goBack(): void {\r\n this.navCtrl.back({ animation: customBackTransition });\r\n }\r\n \r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop;\r\n const threshold = 160;\r\n const fadeDistance = 200;\r\n const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');\r\n const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');\r\n \r\n // Show title in fixed header when scrolled past threshold\r\n if (scrollTop > threshold) {\r\n header?.classList.add('header-scrolled');\r\n } else {\r\n header?.classList.remove('header-scrolled');\r\n }\r\n \r\n // Fade out header-expandable content based on scroll\r\n if (headerExpandable) {\r\n const fadeProgress = Math.min(scrollTop / fadeDistance, 1);\r\n \r\n // Calculate opacity (1 to 0)\r\n const opacity = 1 - fadeProgress;\r\n \r\n // Calculate transform (0px to -20px upward)\r\n const translateY = fadeProgress * -20;\r\n \r\n // Apply styles\r\n headerExpandable.style.opacity = opacity.toString();\r\n headerExpandable.style.transform = `translateY(${translateY}px)`;\r\n }\r\n }\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n openMessage(messageId: string): void {\r\n console.log('Opening message:', messageId);\r\n // Navigate to message thread detail\r\n }\r\n}\r\n\r\n","import { Component, Input, Output, EventEmitter, signal, OnInit, OnDestroy, AfterViewInit, ElementRef, inject, PLATFORM_ID } from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { \r\n IonTabs, \r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconComponent, DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\n/**\r\n * DsMobileTabsComponent\r\n * \r\n * Responsive tab navigation that adapts from mobile to desktop:\r\n * - Mobile (< 768px): Bottom tab bar with icons + labels\r\n * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar\r\n * \r\n * Wraps ion-tabs to maintain native routing functionality while\r\n * providing a responsive navigation experience with branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tabs\r\n * [tabs]=\"tabsConfig\"\r\n * [avatarInitials]=\"'JD'\"\r\n * (avatarClick)=\"handleAvatarClick()\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tabs',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonTabs,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-tabs.css'],\r\n template: `\r\n <ion-tabs>\r\n <ion-tab-bar \r\n [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\" \r\n class=\"ds-tab-bar\"\r\n [class.ds-tab-bar--desktop]=\"isDesktop()\">\r\n \r\n <!-- Logo (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__logo\">\r\n <svg class=\"logomark\" width=\"32\" height=\"28\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n \r\n <!-- Tab buttons container -->\r\n <div class=\"ds-tab-bar__tabs\" *ngIf=\"tabs\">\r\n <ion-tab-button \r\n *ngFor=\"let tab of tabs; trackBy: trackByTabId\"\r\n [tab]=\"tab.id\"\r\n [attr.data-icon]=\"tab.icon\"\r\n [attr.data-icon-active]=\"tab.iconActive\"\r\n [attr.aria-label]=\"tab.label\"\r\n class=\"ds-tab-button ion-activatable\"\r\n [class.tab-selected]=\"isTabActive(tab.id)\">\r\n <div class=\"tab-icon-ripple\"></div>\r\n <div class=\"tab-icon-wrapper\">\r\n <ds-icon \r\n [name]=\"tab.icon\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-inactive\"\r\n />\r\n <ds-icon \r\n [name]=\"tab.iconActive\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-active\"\r\n />\r\n </div>\r\n <ion-label [attr.aria-hidden]=\"true\">{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n </div>\r\n \r\n <!-- Avatar (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__actions\">\r\n <ds-avatar\r\n [initials]=\"avatarInitials\"\r\n [type]=\"avatarType\"\r\n [src]=\"avatarSrc\"\r\n [iconName]=\"avatarIconName\"\r\n (click)=\"handleAvatarClick()\"\r\n style=\"cursor: pointer;\"\r\n />\r\n </div>\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n `\r\n})\r\nexport class DsMobileTabsComponent implements OnInit, OnDestroy, AfterViewInit {\r\n private platformId = inject(PLATFORM_ID);\r\n private resizeListener?: () => void;\r\n private mutationObserver?: MutationObserver;\r\n \r\n // Inputs\r\n @Input() tabs: TabConfig[] = [];\r\n \r\n // Avatar inputs\r\n @Input() avatarType: 'initials' | 'photo' | 'icon' = 'initials';\r\n @Input() avatarInitials: string = 'U';\r\n @Input() avatarSrc: string = '';\r\n @Input() avatarIconName: string = 'remixUser3Line';\r\n \r\n // Outputs\r\n @Output() avatarClick = new EventEmitter<void>();\r\n \r\n // Internal state\r\n activeTab = signal<string>('');\r\n isDesktop = signal<boolean>(false);\r\n \r\n constructor(private elementRef: ElementRef) {}\r\n \r\n ngOnInit(): void {\r\n console.log('DsMobileTabsComponent initialized');\r\n \r\n // Only run breakpoint detection in browser\r\n if (isPlatformBrowser(this.platformId)) {\r\n // Initial check\r\n this.checkBreakpoint();\r\n \r\n // Listen for window resize\r\n this.resizeListener = () => this.checkBreakpoint();\r\n window.addEventListener('resize', this.resizeListener);\r\n }\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial removal\r\n this.removeTitleAttributes();\r\n \r\n // Set up mutation observer to continuously remove title attributes\r\n this.setupTitleRemovalObserver();\r\n }\r\n \r\n ngOnDestroy(): void {\r\n if (isPlatformBrowser(this.platformId) && this.resizeListener) {\r\n window.removeEventListener('resize', this.resizeListener);\r\n }\r\n if (this.mutationObserver) {\r\n this.mutationObserver.disconnect();\r\n }\r\n }\r\n \r\n private setupTitleRemovalObserver(): void {\r\n const config = { \r\n attributes: true, \r\n attributeFilter: ['title'],\r\n subtree: true,\r\n childList: true\r\n };\r\n \r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'attributes' && mutation.attributeName === 'title') {\r\n const target = mutation.target as HTMLElement;\r\n if (target.tagName === 'ION-TAB-BUTTON' && target.hasAttribute('title')) {\r\n target.removeAttribute('title');\r\n }\r\n }\r\n });\r\n // Also do a sweep after any changes\r\n this.removeTitleAttributes();\r\n });\r\n \r\n this.mutationObserver.observe(this.elementRef.nativeElement, config);\r\n }\r\n \r\n private removeTitleAttributes(): void {\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n tabButtons.forEach((button: HTMLElement) => {\r\n if (button.hasAttribute('title')) {\r\n button.removeAttribute('title');\r\n }\r\n // Also remove from the native button inside shadow DOM\r\n const nativeButton = button.shadowRoot?.querySelector('button');\r\n if (nativeButton?.hasAttribute('title')) {\r\n nativeButton.removeAttribute('title');\r\n }\r\n });\r\n }\r\n \r\n private checkBreakpoint(): void {\r\n // 768px matches the @media (min-width: 768px) in CSS\r\n this.isDesktop.set(window.innerWidth >= 768);\r\n }\r\n \r\n trackByTabId(index: number, tab: TabConfig): string {\r\n return tab.id;\r\n }\r\n \r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n \r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, OnInit } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { UserService } from '../services/user.service';\r\nimport { DsMobileTabsComponent, TabConfig } from '../components/ds-mobile-tabs';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileActionsBottomSheetComponent, ActionResult } from '../components/bottom-sheet';\r\n\r\n@Component({\r\n selector: 'app-mobile-tabs-example',\r\n standalone: true,\r\n imports: [DsMobileTabsComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n height: 100vh;\r\n width: 100vw;\r\n position: relative;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-tabs\r\n [tabs]=\"tabs\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n (avatarClick)=\"handleAvatarClick()\"\r\n />\r\n `\r\n})\r\nexport class MobileTabsExampleComponent implements OnInit {\r\n constructor(\r\n public userService: UserService,\r\n private modalController: ModalController,\r\n private router: Router\r\n ) {\r\n console.log('MobileTabsExampleComponent constructor');\r\n }\r\n \r\n ngOnInit() {\r\n console.log('MobileTabsExampleComponent ngOnInit');\r\n // Configure user avatar globally - this is now the single source of truth\r\n this.userService.setAvatarInitials('LM');\r\n this.userService.setAvatarType('initials');\r\n }\r\n \r\n tabs: TabConfig[] = [\r\n {\r\n id: 'home',\r\n label: 'Hjem',\r\n route: 'home',\r\n icon: 'remixHomeSmile2Line',\r\n iconActive: 'remixHomeSmile2Fill'\r\n },\r\n {\r\n id: 'inquiries',\r\n label: 'Henvendelser',\r\n route: 'inquiries',\r\n icon: 'remixFileList3Line',\r\n iconActive: 'remixFileList3Fill'\r\n },\r\n {\r\n id: 'announcements',\r\n label: 'Fællesskab',\r\n route: 'announcements',\r\n icon: 'remixCommunityLine',\r\n iconActive: 'remixCommunityFill'\r\n },\r\n {\r\n id: 'handbook',\r\n label: 'Håndbog',\r\n route: 'handbook',\r\n icon: 'remixBook2Line',\r\n iconActive: 'remixBook2Fill'\r\n }\r\n ];\r\n \r\n async handleAvatarClick(): Promise<void> {\r\n console.log('Avatar clicked - opening profile bottom sheet');\r\n \r\n const sheet = await this.modalController.create({\r\n component: DsMobileActionsBottomSheetComponent,\r\n componentProps: {\r\n customActionGroups: [\r\n {\r\n actions: [\r\n {\r\n action: 'profile',\r\n title: 'Min profil',\r\n icon: 'remixUser3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'settings',\r\n title: 'Indstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'whitelabel-demo',\r\n title: 'Whitelabel Demo',\r\n icon: 'remixPaletteLine',\r\n destructive: false\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'logout',\r\n title: 'Log ud',\r\n icon: 'remixLogoutBoxLine',\r\n destructive: true\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n // Auto-height: no breakpoints, no handle\r\n cssClass: 'ds-bottom-sheet auto-height'\r\n });\r\n \r\n await sheet.present();\r\n \r\n const result = await sheet.onWillDismiss<ActionResult>();\r\n if (result.data?.action) {\r\n console.log('Profile action selected:', result.data.action);\r\n \r\n switch (result.data.action) {\r\n case 'logout':\r\n console.log('Logging out...');\r\n // TODO: Implement logout logic\r\n break;\r\n case 'profile':\r\n console.log('Opening profile...');\r\n // TODO: Navigate to profile page\r\n break;\r\n case 'settings':\r\n console.log('Opening settings...');\r\n // TODO: Navigate to settings page\r\n break;\r\n case 'whitelabel-demo':\r\n console.log('Opening whitelabel demo...');\r\n this.router.navigate(['/whitelabel-demo']);\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n","import { Component, signal, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\r\nimport { Router, ActivatedRoute } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport {\r\n DsAvatarComponent,\r\n DsIconComponent,\r\n DsButtonComponent\r\n} from '@propbinder/design-system';\r\nimport { DsMobilePageDetailsComponent } from '../components/page-details';\r\nimport { UserService } from '../services/user.service';\r\n\r\n/**\r\n * PostCreatePageComponent\r\n * \r\n * Full-screen detail page for creating new posts in the community feed.\r\n * Features Threads-inspired interface with rich text editing capabilities.\r\n */\r\n@Component({\r\n selector: 'app-post-create-page',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsAvatarComponent,\r\n DsIconComponent,\r\n DsButtonComponent,\r\n DsMobilePageDetailsComponent\r\n ],\r\n styles: [`\r\n .post-create-container {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n max-width: 640px;\r\n }\r\n \r\n /* ============================================\r\n CONTENT AREA\r\n ============================================ */\r\n \r\n .content {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n }\r\n \r\n .post-composer {\r\n display: flex;\r\n gap: 12px;\r\n margin-bottom: 24px;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-composer__avatar {\r\n flex-shrink: 0;\r\n padding-top: 2px;\r\n }\r\n \r\n .post-composer__main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .post-composer__header {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 32px;\r\n }\r\n \r\n .post-composer__username {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 15px;\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .post-composer__textarea {\r\n width: 100%;\r\n min-height: 120px;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 15px;\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n background: transparent;\r\n padding: 0;\r\n }\r\n \r\n .post-composer__textarea::placeholder {\r\n color: var(--color-text-tertiary, #999999);\r\n }\r\n \r\n .post-composer__actions {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 16px;\r\n }\r\n \r\n .post-composer__action-btns {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n \r\n .post-composer__action-btn {\r\n background: none;\r\n border: none;\r\n padding: 0;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-text-secondary, #737373);\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .post-composer__action-btn:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n /* Thread connector line */\r\n .thread-line {\r\n position: absolute;\r\n left: 35px;\r\n top: 60px;\r\n bottom: 0;\r\n width: 2px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n /* ============================================\r\n MOBILE OPTIMIZATIONS\r\n ============================================ */\r\n \r\n @media (max-width: 768px) {\r\n .content {\r\n padding: 12px 16px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-details\r\n [title]=\"pageTitle()\"\r\n [backRoute]=\"'/mobile-tabs-example/announcements'\"\r\n (back)=\"handleCancel()\">\r\n \r\n <div class=\"post-create-container\">\r\n <div class=\"post-composer\">\r\n <div class=\"post-composer__avatar\">\r\n <ds-avatar \r\n [initials]=\"userService.avatarInitials()\"\r\n [type]=\"userService.avatarType()\"\r\n [src]=\"userService.avatarSrc()\"\r\n size=\"md\" />\r\n </div>\r\n \r\n <div class=\"post-composer__main\">\r\n <div class=\"post-composer__header\">\r\n <span class=\"post-composer__username\">{{ username() }}</span>\r\n </div>\r\n \r\n <textarea\r\n #textareaInput\r\n class=\"post-composer__textarea\"\r\n [(ngModel)]=\"postContent\"\r\n [placeholder]=\"placeholder()\"\r\n (input)=\"handleInput()\">\r\n </textarea>\r\n \r\n <div class=\"post-composer__actions\">\r\n <div class=\"post-composer__action-btns\">\r\n <button class=\"post-composer__action-btn\" (click)=\"handleAddImage()\">\r\n <ds-icon name=\"remixImageLine\" size=\"22px\" />\r\n </button>\r\n <button class=\"post-composer__action-btn\" (click)=\"handleAddEmoji()\">\r\n <ds-icon name=\"remixEmotionLine\" size=\"22px\" />\r\n </button>\r\n </div>\r\n \r\n <ds-button\r\n variant=\"primary\"\r\n size=\"md\"\r\n [disabled]=\"!canPost()\"\r\n (clicked)=\"handlePost()\">\r\n {{ submitButtonLabel() }}\r\n </ds-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-page-details>\r\n `\r\n})\r\nexport class PostCreatePageComponent implements AfterViewInit, OnInit {\r\n @ViewChild('textareaInput') textareaInput?: ElementRef<HTMLTextAreaElement>;\r\n \r\n postContent = '';\r\n username = signal('Lars Mikkelsen');\r\n placeholder = signal(\"What's new?\");\r\n \r\n // Edit mode state\r\n isEditMode = signal(false);\r\n postId = signal<string | null>(null);\r\n pageTitle = signal('New post');\r\n submitButtonLabel = signal('Post');\r\n \r\n constructor(\r\n private router: Router,\r\n private route: ActivatedRoute,\r\n public userService: UserService\r\n ) {}\r\n \r\n ngOnInit(): void {\r\n // Check for edit mode via query parameters\r\n this.route.queryParams.subscribe(params => {\r\n const editMode = params['edit'] === 'true';\r\n const postId = params['id'];\r\n const content = params['content'];\r\n \r\n if (editMode && postId) {\r\n this.isEditMode.set(true);\r\n this.postId.set(postId);\r\n this.pageTitle.set('Edit post');\r\n this.submitButtonLabel.set('Save');\r\n \r\n // Prefill content if provided\r\n if (content) {\r\n this.postContent = decodeURIComponent(content);\r\n }\r\n } else {\r\n // Reset to create mode\r\n this.isEditMode.set(false);\r\n this.postId.set(null);\r\n this.pageTitle.set('New post');\r\n this.submitButtonLabel.set('Post');\r\n this.postContent = '';\r\n }\r\n });\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Focus the textarea after view initialization to trigger keyboard on mobile\r\n setTimeout(() => {\r\n this.textareaInput?.nativeElement.focus();\r\n }, 300);\r\n }\r\n \r\n handleInput(): void {\r\n // Handle text input changes\r\n }\r\n \r\n canPost(): boolean {\r\n return this.postContent.trim().length > 0;\r\n }\r\n \r\n handleCancel(): void {\r\n if (this.postContent.trim().length > 0) {\r\n // Show confirmation dialog\r\n const confirmed = confirm('Discard this post?');\r\n if (confirmed) {\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n } else {\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n }\r\n \r\n handlePost(): void {\r\n if (!this.canPost()) return;\r\n \r\n if (this.isEditMode()) {\r\n console.log('Updating post:', this.postId(), this.postContent);\r\n // TODO: Implement post update logic\r\n // this.postService.updatePost(this.postId(), this.postContent).subscribe(() => {\r\n // this.router.navigate(['/mobile-tabs-example/community']);\r\n // });\r\n } else {\r\n console.log('Creating post:', this.postContent);\r\n // TODO: Implement post creation logic\r\n // this.postService.createPost(this.postContent).subscribe(() => {\r\n // this.router.navigate(['/mobile-tabs-example/community']);\r\n // });\r\n }\r\n \r\n // For now, just navigate back\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n \r\n handleAddImage(): void {\r\n console.log('Add image');\r\n // TODO: Open image picker\r\n }\r\n \r\n handleAddEmoji(): void {\r\n console.log('Add emoji');\r\n // TODO: Open emoji picker\r\n }\r\n}\r\n\r\n","import { Component } from '@angular/core';\r\nimport { DsMobilePageDetailsComponent } from '../components/page-details';\r\nimport { \r\n DsMobilePostCardComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../components/post-card';\r\nimport { DsMobileCommentComponent } from '../components/comment';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../components/lightbox';\r\nimport { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';\r\nimport { DsMobileCommentActionsBottomSheetComponent, CommentActionResult } from '../components/bottom-sheet';\r\n\r\n@Component({\r\n selector: 'app-mobile-post-detail-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageDetailsComponent,\r\n DsMobilePostCardComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCommentComponent\r\n ],\r\n styles: [`\r\n .post-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n max-width: 640px;\r\n }\r\n \r\n .post-section {\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding-bottom: 16px;\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n .comments-section {\r\n display: flex;\r\n flex-direction: column;\r\n /* Negative margin to pull comments out by 8px on each side */\r\n /* Page has 20px padding, this makes comments effectively 12px from edge */\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n .comments-header {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 18px;\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin-bottom: 16px;\r\n /* Add padding to keep header at 20px from edge (8px to offset negative margin) */\r\n padding-left: 8px;\r\n padding-right: 8px;\r\n }\r\n \r\n .comments-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-details title=\"Opslag\">\r\n <div class=\"post-detail-container\">\r\n <!-- Post Section -->\r\n <div class=\"post-section\">\r\n <ds-mobile-post-card\r\n [authorName]=\"'Sophie Andersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'4t siden'\"\r\n [avatarInitials]=\"'SA'\"\r\n [variant]=\"'detail'\">\r\n \r\n <post-content class=\"no-indent\">\r\n <post-text>Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️</post-text>\r\n <post-media>\r\n <img \r\n src=\"/Assets/Dummy-photos/balcony-view.jpg\" \r\n alt=\"Altanudsigt\" \r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox('/Assets/Dummy-photos/balcony-view.jpg', 'Altanudsigt', 'Morgenkaffe har aldrig smagt så godt ☕️')\"\r\n />\r\n </post-media>\r\n </post-content>\r\n \r\n <post-actions class=\"no-indent\">\r\n <action-like [active]=\"true\" [count]=\"156\" />\r\n <action-comment [count]=\"34\" />\r\n </post-actions>\r\n </ds-mobile-post-card>\r\n </div>\r\n \r\n <!-- Comments Section -->\r\n <div class=\"comments-section\">\r\n <h2 class=\"comments-header\">{{ repliesCount }} svar</h2>\r\n \r\n <div class=\"comments-list\">\r\n <ds-mobile-comment\r\n [authorName]=\"'Anders Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3t siden'\"\r\n [avatarInitials]=\"'AJ'\"\r\n [content]=\"'Wow, den udsigt er fantastisk! Hvilken etage er du på?'\"\r\n [likeCount]=\"12\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Anders Jensen', 'Wow, den udsigt er fantastisk! Hvilken etage er du på?', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Thomas Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3t siden'\"\r\n [avatarInitials]=\"'TH'\"\r\n [content]=\"'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆'\"\r\n [isLiked]=\"true\"\r\n [likeCount]=\"8\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"true\"\r\n (longPress)=\"handleCommentLongPress('Thomas Hansen', 'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆', true)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Emma Petersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarInitials]=\"'EP'\"\r\n [content]=\"'Dette er præcis derfor jeg elsker at bo her. Godt billede!'\"\r\n [likeCount]=\"15\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Emma Petersen', 'Dette er præcis derfor jeg elsker at bo her. Godt billede!', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Nikolaj Sørensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarInitials]=\"'NS'\"\r\n [content]=\"'Solnedgangene fra den vinkel må være utrolige'\"\r\n [likeCount]=\"6\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Nikolaj Sørensen', 'Solnedgangene fra den vinkel må være utrolige', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Mette Larsen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1t siden'\"\r\n [avatarInitials]=\"'ML'\"\r\n [content]=\"'Giver mig lyst til at få min morgenkaffe på altanen også! ☕'\"\r\n [likeCount]=\"9\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Mette Larsen', 'Giver mig lyst til at få min morgenkaffe på altanen også! ☕', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Frederik Nielsen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1t siden'\"\r\n [avatarInitials]=\"'FN'\"\r\n [content]=\"'Heldig! Min altan vender den anden vej, men stadig pæn'\"\r\n [likeCount]=\"4\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Frederik Nielsen', 'Heldig! Min altan vender den anden vej, men stadig pæn', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Caroline Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'45m siden'\"\r\n [avatarInitials]=\"'CJ'\"\r\n [content]=\"'Denne bygning har den bedste udsigt i byen, uden tvivl'\"\r\n [likeCount]=\"11\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Caroline Jensen', 'Denne bygning har den bedste udsigt i byen, uden tvivl', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Anna Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'30m siden'\"\r\n [avatarInitials]=\"'AH'\"\r\n [content]=\"'Jeg skal se din altan en dag! 😍'\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Anna Hansen', 'Jeg skal se din altan en dag! 😍', false)\" />\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-page-details>\r\n `\r\n})\r\nexport class MobilePostDetailPageComponent {\r\n repliesCount = 6;\r\n \r\n constructor(\r\n private lightbox: DsMobileLightboxService,\r\n private bottomSheet: DsMobileBottomSheetService\r\n ) {}\r\n \r\n /**\r\n * Open an image in the lightbox viewer\r\n */\r\n openImageLightbox(imageSrc: string, title: string, description: string): void {\r\n const authorMeta: LightboxAuthor = {\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n timestamp: '4t siden'\r\n };\r\n \r\n this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: imageSrc,\r\n alt: title,\r\n title: title,\r\n description: description,\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false, // Single image, no need for controls\r\n showInfo: true\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a comment to show action sheet\r\n */\r\n async handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobileCommentActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnComment\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as CommentActionResult).action;\r\n \r\n switch (action) {\r\n case 'like':\r\n console.log('Like comment by', authorName);\r\n // Implement like logic\r\n break;\r\n case 'reply':\r\n console.log('Reply to comment by', authorName);\r\n // Implement reply logic\r\n break;\r\n case 'edit':\r\n console.log('Edit comment by', authorName);\r\n // Implement edit logic\r\n break;\r\n case 'delete':\r\n console.log('Delete comment by', authorName);\r\n // Implement delete logic (with confirmation)\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable, signal, effect } from '@angular/core';\r\n\r\nexport interface WhitelabelConfig {\r\n // Logo assets\r\n logoUrl: string; // Full logo for header (typically horizontal)\r\n logoMarkUrl: string; // Compact logo mark for avatars/badges\r\n logoAlt: string; // Alt text for accessibility\r\n \r\n // Logo dimensions (optional, for optimization)\r\n logoWidth?: number;\r\n logoHeight?: number;\r\n logoMarkWidth?: number;\r\n logoMarkHeight?: number;\r\n \r\n // Brand colors - these will update CSS custom properties\r\n primaryColor: string; // Maps to --color-background-brand\r\n secondaryColor: string; // Maps to --color-brand-secondary\r\n \r\n // Organization info\r\n organizationName: string;\r\n organizationId: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: WhitelabelConfig = {\r\n logoUrl: '/assets/logos/propbinder-logo.svg',\r\n logoMarkUrl: '/assets/logos/propbinder-logomark.svg',\r\n logoAlt: 'Propbinder',\r\n primaryColor: '#6B5FF5', // Propbinder brand purple (--color-background-brand)\r\n secondaryColor: '#221a4c', // Propbinder dark purple for headers (--color-brand-secondary)\r\n organizationName: 'Propbinder',\r\n organizationId: 'default'\r\n};\r\n\r\n/**\r\n * WhitelabelService\r\n * \r\n * Manages whitelabel configuration including logos and brand colors.\r\n * Automatically updates CSS custom properties when colors change.\r\n * \r\n * @example\r\n * Initialize with custom config:\r\n * ```typescript\r\n * whitelabelService.initialize({\r\n * logoUrl: '/assets/logos/acme-logo.svg',\r\n * logoMarkUrl: '/assets/logos/acme-mark.svg',\r\n * primaryColor: '#2563eb',\r\n * secondaryColor: '#3b82f6',\r\n * organizationName: 'Acme Corp'\r\n * });\r\n * ```\r\n * \r\n * Load from API:\r\n * ```typescript\r\n * await whitelabelService.loadFromApi('acme-corp');\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class WhitelabelService {\r\n private _config = signal<WhitelabelConfig>(DEFAULT_CONFIG);\r\n \r\n // Readonly getters for accessing config values\r\n readonly logoUrl = () => this._config().logoUrl;\r\n readonly logoMarkUrl = () => this._config().logoMarkUrl;\r\n readonly logoAlt = () => this._config().logoAlt;\r\n readonly primaryColor = () => this._config().primaryColor;\r\n readonly secondaryColor = () => this._config().secondaryColor;\r\n readonly organizationName = () => this._config().organizationName;\r\n readonly organizationId = () => this._config().organizationId;\r\n \r\n // Full config accessor\r\n readonly config = this._config.asReadonly();\r\n \r\n constructor() {\r\n // Apply default colors on initialization\r\n this.applyColors(DEFAULT_CONFIG.primaryColor, DEFAULT_CONFIG.secondaryColor);\r\n \r\n // Watch for config changes and update CSS custom properties\r\n effect(() => {\r\n const config = this._config();\r\n this.applyColors(config.primaryColor, config.secondaryColor);\r\n });\r\n }\r\n \r\n /**\r\n * Initialize whitelabel configuration\r\n * Call this early in app initialization (app.config.ts or app.component.ts)\r\n */\r\n initialize(config: Partial<WhitelabelConfig>) {\r\n this._config.update(current => ({\r\n ...current,\r\n ...config\r\n }));\r\n }\r\n \r\n /**\r\n * Load whitelabel config from API\r\n * Typically called on app startup based on subdomain, user tenant, etc.\r\n * \r\n * @param organizationId - The organization identifier (subdomain, tenant ID, etc.)\r\n */\r\n async loadFromApi(organizationId?: string): Promise<void> {\r\n try {\r\n // Example API call structure\r\n // const response = await fetch(`/api/whitelabel/${organizationId || 'default'}`);\r\n // const config = await response.json();\r\n // this.initialize(config);\r\n \r\n console.log('Loading whitelabel config from API for:', organizationId);\r\n \r\n // Example: Different configs for different organizations\r\n if (organizationId === 'demo-client') {\r\n this.initialize({\r\n logoUrl: '/assets/logos/demo-logo.svg',\r\n logoMarkUrl: '/assets/logos/demo-mark.svg',\r\n logoAlt: 'Demo Client',\r\n primaryColor: '#2563eb', // Blue\r\n secondaryColor: '#3b82f6', // Lighter blue\r\n organizationName: 'Demo Client',\r\n organizationId: 'demo-client'\r\n });\r\n }\r\n // Add more organization-specific configs as needed\r\n \r\n } catch (error) {\r\n console.error('Failed to load whitelabel config:', error);\r\n // Fallback to defaults already set\r\n }\r\n }\r\n \r\n /**\r\n * Update config dynamically (e.g., when user switches organizations)\r\n */\r\n updateConfig(updates: Partial<WhitelabelConfig>) {\r\n this.initialize(updates);\r\n }\r\n \r\n /**\r\n * Update only the brand colors\r\n */\r\n updateColors(primaryColor: string, secondaryColor: string) {\r\n this._config.update(current => ({\r\n ...current,\r\n primaryColor,\r\n secondaryColor\r\n }));\r\n }\r\n \r\n /**\r\n * Reset to default configuration\r\n */\r\n resetToDefault() {\r\n this._config.set(DEFAULT_CONFIG);\r\n }\r\n \r\n /**\r\n * Apply colors to CSS custom properties\r\n * This updates the actual CSS variables used throughout the app\r\n */\r\n private applyColors(primaryColor: string, secondaryColor: string) {\r\n if (typeof document !== 'undefined') {\r\n const root = document.documentElement;\r\n root.style.setProperty('--color-background-brand', primaryColor);\r\n root.style.setProperty('--color-brand-secondary', secondaryColor);\r\n \r\n console.log('Applied whitelabel colors:', { primaryColor, secondaryColor });\r\n }\r\n }\r\n}\r\n\r\n","import { Component, Input, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { WhitelabelService } from '../../services/whitelabel.service';\r\n\r\nexport type LogoVariant = 'full' | 'mark';\r\nexport type LogoSize = 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * DsLogoComponent\r\n * \r\n * Displays the whitelabeled logo or logomark based on current configuration.\r\n * Automatically pulls logo assets from WhitelabelService.\r\n * \r\n * @example\r\n * Full logo in header:\r\n * ```html\r\n * <ds-logo variant=\"full\" size=\"md\" />\r\n * ```\r\n * \r\n * Logomark for compact spaces:\r\n * ```html\r\n * <ds-logo variant=\"mark\" size=\"sm\" />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-logo',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n line-height: 0;\r\n }\r\n \r\n .logo {\r\n display: block;\r\n object-fit: contain;\r\n }\r\n \r\n /* Size variants for full logo */\r\n .logo--full.logo--sm { height: 24px; width: auto; }\r\n .logo--full.logo--md { height: 32px; width: auto; }\r\n .logo--full.logo--lg { height: 40px; width: auto; }\r\n .logo--full.logo--xl { height: 48px; width: auto; }\r\n \r\n /* Size variants for logomark */\r\n .logo--mark.logo--sm { height: 20px; width: 20px; }\r\n .logo--mark.logo--md { height: 28px; width: 28px; }\r\n .logo--mark.logo--lg { height: 36px; width: 36px; }\r\n .logo--mark.logo--xl { height: 44px; width: 44px; }\r\n `],\r\n template: `\r\n <img \r\n [src]=\"logoSrc()\"\r\n [alt]=\"logoAlt()\"\r\n [class]=\"logoClasses()\"\r\n [style.height.px]=\"customHeight\"\r\n [style.width.px]=\"customWidth\"\r\n />\r\n `\r\n})\r\nexport class DsLogoComponent {\r\n private whitelabelService = inject(WhitelabelService);\r\n \r\n @Input() variant: LogoVariant = 'full';\r\n @Input() size: LogoSize = 'md';\r\n @Input() customHeight?: number;\r\n @Input() customWidth?: number;\r\n \r\n logoSrc = computed(() => {\r\n return this.variant === 'full' \r\n ? this.whitelabelService.logoUrl()\r\n : this.whitelabelService.logoMarkUrl();\r\n });\r\n \r\n logoAlt = computed(() => {\r\n const alt = this.whitelabelService.logoAlt();\r\n return this.variant === 'full' ? alt : `${alt} logo`;\r\n });\r\n \r\n logoClasses = computed(() => {\r\n return `logo logo--${this.variant} logo--${this.size}`;\r\n });\r\n}\r\n\r\n","import { Component, Input, computed, ViewEncapsulation } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsLogoComponent } from '../logo/ds-logo';\r\n\r\nexport type AvatarType = 'initials' | 'photo' | 'icon';\r\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\nexport type BadgePosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';\r\n\r\n/**\r\n * DsAvatarWithBadgeComponent\r\n * \r\n * Displays an avatar with a logomark badge overlay.\r\n * Useful for showing user avatars with organization branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-avatar-with-badge\r\n * [type]=\"'initials'\"\r\n * [initials]=\"'JD'\"\r\n * [size]=\"'lg'\"\r\n * [badgePosition]=\"'bottom-right'\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-avatar-with-badge',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsLogoComponent],\r\n encapsulation: ViewEncapsulation.Emulated,\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n position: relative;\r\n }\r\n \r\n .avatar-badge-container {\r\n position: relative;\r\n display: inline-block;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n background: white;\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\r\n }\r\n \r\n /* Badge positioning */\r\n .avatar-badge--bottom-right {\r\n bottom: 0;\r\n right: 0;\r\n }\r\n \r\n .avatar-badge--bottom-left {\r\n bottom: 0;\r\n left: 0;\r\n }\r\n \r\n .avatar-badge--top-right {\r\n top: 0;\r\n right: 0;\r\n }\r\n \r\n .avatar-badge--top-left {\r\n top: 0;\r\n left: 0;\r\n }\r\n \r\n /* Badge sizes based on avatar size */\r\n .avatar-badge--xs { width: 16px; height: 16px; padding: 3px; }\r\n .avatar-badge--sm { width: 20px; height: 20px; padding: 3px; }\r\n .avatar-badge--md { width: 24px; height: 24px; padding: 4px; }\r\n .avatar-badge--lg { width: 32px; height: 32px; padding: 5px; }\r\n .avatar-badge--xl { width: 40px; height: 40px; padding: 6px; }\r\n `],\r\n template: `\r\n <div class=\"avatar-badge-container\">\r\n <ds-avatar\r\n [type]=\"type\"\r\n [size]=\"size\"\r\n [initials]=\"initials\"\r\n [src]=\"src\"\r\n [iconName]=\"iconName\"\r\n />\r\n \r\n @if (showBadge) {\r\n <div [class]=\"badgeClasses()\">\r\n <ds-logo \r\n variant=\"mark\" \r\n [customHeight]=\"badgeLogoSize()\"\r\n [customWidth]=\"badgeLogoSize()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsAvatarWithBadgeComponent {\r\n // Avatar props\r\n @Input() type: AvatarType = 'initials';\r\n @Input() size: AvatarSize = 'md';\r\n @Input() initials: string = '';\r\n @Input() src: string = '';\r\n @Input() iconName: string = 'remixUser3Fill';\r\n \r\n // Badge props\r\n @Input() showBadge: boolean = true;\r\n @Input() badgePosition: BadgePosition = 'bottom-right';\r\n \r\n badgeClasses = computed(() => {\r\n return `avatar-badge avatar-badge--${this.badgePosition} avatar-badge--${this.size}`;\r\n });\r\n \r\n // Calculate badge logo size based on avatar size\r\n badgeLogoSize = computed(() => {\r\n const sizeMap: Record<AvatarSize, number> = {\r\n xs: 10,\r\n sm: 14,\r\n md: 16,\r\n lg: 22,\r\n xl: 28\r\n };\r\n return sizeMap[this.size];\r\n });\r\n}\r\n\r\n","import { Component, OnInit, inject, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { WhitelabelService } from '../services/whitelabel.service';\r\nimport { DsLogoComponent } from '../components/logo/ds-logo';\r\nimport { DsAvatarWithBadgeComponent } from '../components/avatar-with-badge/ds-avatar-with-badge';\r\nimport { IonContent, IonHeader, IonToolbar, IonTitle, IonButton } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Whitelabel Demo Page\r\n * \r\n * Demonstrates the whitelabeling system with live color and logo switching.\r\n */\r\n@Component({\r\n selector: 'app-whitelabel-demo',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonButton,\r\n DsLogoComponent,\r\n DsAvatarWithBadgeComponent\r\n ],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n ion-toolbar {\r\n --background: var(--color-brand-secondary);\r\n --color: white;\r\n }\r\n \r\n ion-content {\r\n --background: #f5f5f5;\r\n }\r\n \r\n .demo-container {\r\n padding: 20px;\r\n max-width: 800px;\r\n margin: 0 auto;\r\n }\r\n \r\n .demo-section {\r\n margin-bottom: 32px;\r\n }\r\n \r\n .demo-section h2 {\r\n margin-bottom: 16px;\r\n font-size: 20px;\r\n font-weight: 600;\r\n }\r\n \r\n .logo-showcase {\r\n display: flex;\r\n gap: 24px;\r\n align-items: center;\r\n padding: 24px;\r\n background: white;\r\n border-radius: 8px;\r\n }\r\n \r\n .avatar-showcase {\r\n display: flex;\r\n gap: 16px;\r\n align-items: center;\r\n padding: 24px;\r\n background: white;\r\n border-radius: 8px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n .button-group {\r\n display: flex;\r\n gap: 12px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n .color-demo {\r\n padding: 24px;\r\n background: white;\r\n border-radius: 8px;\r\n }\r\n \r\n .color-swatch {\r\n display: flex;\r\n gap: 16px;\r\n margin-top: 16px;\r\n }\r\n \r\n .swatch {\r\n flex: 1;\r\n min-height: 100px;\r\n border-radius: 8px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: white;\r\n font-weight: 600;\r\n }\r\n \r\n .swatch--primary {\r\n background: var(--color-background-brand);\r\n }\r\n \r\n .swatch--secondary {\r\n background: var(--color-brand-secondary);\r\n }\r\n \r\n .current-config {\r\n padding: 16px;\r\n background: #f5f5f5;\r\n border-radius: 8px;\r\n margin-top: 16px;\r\n }\r\n \r\n .current-config pre {\r\n margin: 0;\r\n font-size: 12px;\r\n overflow-x: auto;\r\n }\r\n \r\n .color-inputs {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n margin-top: 16px;\r\n }\r\n \r\n .color-input-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .color-input-row label {\r\n min-width: 100px;\r\n font-weight: 600;\r\n font-size: 14px;\r\n }\r\n \r\n .color-input-row input[type=\"color\"] {\r\n width: 50px;\r\n height: 40px;\r\n border: none;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n }\r\n \r\n .color-input-row input[type=\"text\"] {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: 1px solid #ddd;\r\n border-radius: 8px;\r\n font-family: monospace;\r\n font-size: 14px;\r\n }\r\n \r\n .logo-upload {\r\n margin-top: 24px;\r\n padding: 20px;\r\n background: white;\r\n border-radius: 8px;\r\n }\r\n \r\n .upload-section {\r\n margin-bottom: 20px;\r\n }\r\n \r\n .upload-section h3 {\r\n font-size: 16px;\r\n font-weight: 600;\r\n margin-bottom: 12px;\r\n }\r\n \r\n .file-input-wrapper {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .file-input-wrapper input[type=\"file\"] {\r\n display: none;\r\n }\r\n \r\n .upload-button {\r\n padding: 10px 16px;\r\n background: var(--color-background-brand);\r\n color: white;\r\n border: none;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n font-weight: 600;\r\n font-size: 14px;\r\n }\r\n \r\n .upload-button:hover {\r\n opacity: 0.9;\r\n }\r\n \r\n .file-name {\r\n font-size: 14px;\r\n color: #666;\r\n }\r\n \r\n .reset-button {\r\n padding: 8px 12px;\r\n background: #f5f5f5;\r\n color: #666;\r\n border: 1px solid #ddd;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n }\r\n `],\r\n template: `\r\n <ion-header>\r\n <ion-toolbar>\r\n <ion-title>Whitelabel Demo</ion-title>\r\n </ion-toolbar>\r\n </ion-header>\r\n \r\n <ion-content>\r\n <div class=\"demo-container\">\r\n <!-- Logo Section -->\r\n <div class=\"demo-section\">\r\n <h2>Logos</h2>\r\n <div class=\"logo-showcase\">\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Full Logo (md)</p>\r\n <ds-logo variant=\"full\" size=\"md\" />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Logomark (sm)</p>\r\n <ds-logo variant=\"mark\" size=\"sm\" />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Logomark (md)</p>\r\n <ds-logo variant=\"mark\" size=\"md\" />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Logomark (lg)</p>\r\n <ds-logo variant=\"mark\" size=\"lg\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Logo Upload Section -->\r\n <div class=\"logo-upload\">\r\n <div class=\"upload-section\">\r\n <h3>Upload Full Logo</h3>\r\n <div class=\"file-input-wrapper\">\r\n <input \r\n #fullLogoInput\r\n type=\"file\" \r\n accept=\"image/*\"\r\n (change)=\"handleFullLogoUpload($event)\"\r\n />\r\n <button class=\"upload-button\" (click)=\"fullLogoInput.click()\">\r\n Choose File\r\n </button>\r\n @if (uploadedFullLogoName) {\r\n <span class=\"file-name\">{{ uploadedFullLogoName }}</span>\r\n }\r\n @if (uploadedFullLogoName) {\r\n <button class=\"reset-button\" (click)=\"resetFullLogo()\">Reset</button>\r\n }\r\n </div>\r\n </div>\r\n \r\n <div class=\"upload-section\">\r\n <h3>Upload Logomark</h3>\r\n <div class=\"file-input-wrapper\">\r\n <input \r\n #logomarkInput\r\n type=\"file\" \r\n accept=\"image/*\"\r\n (change)=\"handleLogomarkUpload($event)\"\r\n />\r\n <button class=\"upload-button\" (click)=\"logomarkInput.click()\">\r\n Choose File\r\n </button>\r\n @if (uploadedLogomarkName) {\r\n <span class=\"file-name\">{{ uploadedLogomarkName }}</span>\r\n }\r\n @if (uploadedLogomarkName) {\r\n <button class=\"reset-button\" (click)=\"resetLogomark()\">Reset</button>\r\n }\r\n </div>\r\n </div>\r\n \r\n <p style=\"font-size: 12px; color: #999; margin-top: 12px;\">\r\n Tip: Use SVG or PNG files with transparent backgrounds for best results\r\n </p>\r\n </div>\r\n </div>\r\n \r\n <!-- Avatar with Badge Section -->\r\n <div class=\"demo-section\">\r\n <h2>Avatar with Logo Badge</h2>\r\n <div class=\"avatar-showcase\">\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Small</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'sm'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Medium</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'md'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Large</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'lg'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">X-Large</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'xl'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Color Section -->\r\n <div class=\"demo-section\">\r\n <h2>Brand Colors</h2>\r\n <div class=\"color-demo\">\r\n <p style=\"margin-bottom: 8px; color: #666;\">Current brand colors:</p>\r\n <div class=\"color-swatch\">\r\n <div class=\"swatch swatch--primary\">\r\n Primary<br/>\r\n <span style=\"font-size: 11px; opacity: 0.9;\">{{ whitelabelService.primaryColor() }}</span>\r\n </div>\r\n <div class=\"swatch swatch--secondary\">\r\n Secondary<br/>\r\n <span style=\"font-size: 11px; opacity: 0.9;\">{{ whitelabelService.secondaryColor() }}</span>\r\n </div>\r\n </div>\r\n \r\n <!-- Custom Color Inputs -->\r\n <div class=\"color-inputs\">\r\n <div class=\"color-input-row\">\r\n <label>Primary:</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customPrimaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customPrimaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n placeholder=\"#6B5FF5\"\r\n />\r\n </div>\r\n <div class=\"color-input-row\">\r\n <label>Secondary:</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSecondaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSecondaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n placeholder=\"#221a4c\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Theme Switcher -->\r\n <div class=\"demo-section\">\r\n <h2>Switch Organization Theme</h2>\r\n <div class=\"button-group\">\r\n <ion-button (click)=\"applyDefaultTheme()\">\r\n Default (Purple)\r\n </ion-button>\r\n <ion-button (click)=\"applyBlueTheme()\">\r\n Blue Theme\r\n </ion-button>\r\n <ion-button (click)=\"applyGreenTheme()\">\r\n Green Theme\r\n </ion-button>\r\n <ion-button (click)=\"applyOrangeTheme()\">\r\n Orange Theme\r\n </ion-button>\r\n </div>\r\n </div>\r\n \r\n <!-- Current Config -->\r\n <div class=\"demo-section\">\r\n <h2>Current Configuration</h2>\r\n <div class=\"current-config\">\r\n <pre>{{ configJson() }}</pre>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class WhitelabelDemoPage implements OnInit {\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n // Custom color inputs\r\n customPrimaryColor = '#6B5FF5';\r\n customSecondaryColor = '#221a4c';\r\n \r\n // Logo upload state\r\n uploadedFullLogoName = '';\r\n uploadedLogomarkName = '';\r\n \r\n ngOnInit() {\r\n console.log('Whitelabel Demo Page initialized');\r\n // Initialize custom colors with current values\r\n this.customPrimaryColor = this.whitelabelService.primaryColor();\r\n this.customSecondaryColor = this.whitelabelService.secondaryColor();\r\n }\r\n \r\n handleFullLogoUpload(event: Event) {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files[0]) {\r\n const file = input.files[0];\r\n this.uploadedFullLogoName = file.name;\r\n \r\n // Convert to data URL\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const dataUrl = e.target?.result as string;\r\n this.whitelabelService.updateConfig({\r\n logoUrl: dataUrl\r\n });\r\n };\r\n reader.readAsDataURL(file);\r\n }\r\n }\r\n \r\n handleLogomarkUpload(event: Event) {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files[0]) {\r\n const file = input.files[0];\r\n this.uploadedLogomarkName = file.name;\r\n \r\n // Convert to data URL\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const dataUrl = e.target?.result as string;\r\n this.whitelabelService.updateConfig({\r\n logoMarkUrl: dataUrl\r\n });\r\n };\r\n reader.readAsDataURL(file);\r\n }\r\n }\r\n \r\n resetFullLogo() {\r\n this.uploadedFullLogoName = '';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/assets/logos/propbinder-logo.svg'\r\n });\r\n }\r\n \r\n resetLogomark() {\r\n this.uploadedLogomarkName = '';\r\n this.whitelabelService.updateConfig({\r\n logoMarkUrl: '/assets/logos/propbinder-logomark.svg'\r\n });\r\n }\r\n \r\n configJson() {\r\n return JSON.stringify(this.whitelabelService.config(), null, 2);\r\n }\r\n \r\n applyDefaultTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#6B5FF5',\r\n secondaryColor: '#221a4c',\r\n organizationName: 'Propbinder',\r\n organizationId: 'default'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyBlueTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#2563eb',\r\n secondaryColor: '#3b82f6',\r\n organizationName: 'Blue Corp',\r\n organizationId: 'blue-corp'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyGreenTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#16a34a',\r\n secondaryColor: '#22c55e',\r\n organizationName: 'Green Industries',\r\n organizationId: 'green-industries'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyOrangeTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#ea580c',\r\n secondaryColor: '#f97316',\r\n organizationName: 'Orange Solutions',\r\n organizationId: 'orange-solutions'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyCustomColors() {\r\n this.whitelabelService.updateColors(\r\n this.customPrimaryColor,\r\n this.customSecondaryColor\r\n );\r\n }\r\n \r\n private updateCustomColorInputs() {\r\n this.customPrimaryColor = this.whitelabelService.primaryColor();\r\n this.customSecondaryColor = this.whitelabelService.secondaryColor();\r\n }\r\n}\r\n\r\n","/* Auto-generated. Do not edit. */\nexport * from './components';\nexport * from './pages';\nexport * from './animations/page-transitions';\nexport * from './services/user.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.DsMobileLongPressDirective","PostContentComponent","PostTextComponent","PostMediaComponent","PostAttachmentsComponent","PostActionsComponent","ActionLikeComponent","ActionCommentComponent","i1","i2","DsMobileTabsComponent","i1.DsMobileLightboxService","DsMobileCommentActionsBottomSheetComponent","i2.DsMobileLightboxService","i3.DsMobileBottomSheetService","i4","i1.DsMobileHandbookDetailModalService","DsMobilePostActionsBottomSheetComponent","i2.DsMobileBottomSheetService","i3.DsMobileLightboxService","i4.DsMobilePostDetailModalService","i5.UserService","i1.UserService","i2.UserService","i3"],"mappings":"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"}
1
+ {"version":3,"file":"propbinder-mobile-design.mjs","sources":["../../../projects/mobile-design-lib/src/components/shared/mobile-page-base.ts","../../../projects/mobile-design-lib/src/components/shared/directives/long-press.directive.ts","../../../projects/mobile-design-lib/src/components/list-item/ds-mobile-list-item.ts","../../../projects/mobile-design-lib/src/components/action-list-item/ds-mobile-action-list-item.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts","../../../projects/mobile-design-lib/src/components/page-main/ds-mobile-page-main.ts","../../../projects/mobile-design-lib/src/components/page-details/ds-mobile-page-details.ts","../../../projects/mobile-design-lib/src/components/content/ds-mobile-content.ts","../../../projects/mobile-design-lib/src/components/header-content/ds-mobile-header-content.ts","../../../projects/mobile-design-lib/src/components/post-card/ds-mobile-post-card.ts","../../../projects/mobile-design-lib/src/components/comment/ds-mobile-comment.ts","../../../projects/mobile-design-lib/src/components/post-composer/ds-mobile-post-composer.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/index.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts","../../../projects/mobile-design-lib/src/components/contact-list-item/ds-mobile-contact-list-item.ts","../../../projects/mobile-design-lib/src/components/app-layout/ds-mobile-app-layout.ts","../../../projects/mobile-design-lib/src/components/tabs/ds-mobile-tabs.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-header.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-footer.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-image.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-pdf.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox.service.ts","../../../projects/mobile-design-lib/src/components/lightbox/index.ts","../../../projects/mobile-design-lib/src/components/inline-photo/ds-mobile-inline-photo.ts","../../../projects/mobile-design-lib/src/components/modal/ds-mobile-modal.service.ts","../../../projects/mobile-design-lib/src/components/modal/index.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/index.ts","../../../projects/mobile-design-lib/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts","../../../projects/mobile-design-lib/src/components/file-attachment/ds-mobile-file-attachment.ts","../../../projects/mobile-design-lib/src/components/swiper/ds-mobile-swiper.ts","../../../projects/mobile-design-lib/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts","../../../projects/mobile-design-lib/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts","../../../projects/mobile-design-lib/src/components/handbook-folder/ds-mobile-handbook-folder.ts","../../../projects/mobile-design-lib/src/components/index.ts","../../../projects/mobile-design-lib/src/services/user.service.ts","../../../projects/mobile-design-lib/src/pages/community.page.ts","../../../projects/mobile-design-lib/src/pages/handbook.page.ts","../../../projects/mobile-design-lib/src/pages/home.page.ts","../../../projects/mobile-design-lib/src/animations/page-transitions.ts","../../../projects/mobile-design-lib/src/components/tab-bar/ds-mobile-tab-bar.ts","../../../projects/mobile-design-lib/src/pages/inquiries.example.ts","../../../projects/mobile-design-lib/src/components/list-item-static/ds-mobile-list-item-static.ts","../../../projects/mobile-design-lib/src/pages/inquiry-detail.example.ts","../../../projects/mobile-design-lib/src/components/ds-mobile-tabs.ts","../../../projects/mobile-design-lib/src/pages/mobile-tabs-example.component.ts","../../../projects/mobile-design-lib/src/pages/post-create.page.ts","../../../projects/mobile-design-lib/src/pages/post-detail.page.ts","../../../projects/mobile-design-lib/src/services/whitelabel.service.ts","../../../projects/mobile-design-lib/src/components/logo/ds-logo.ts","../../../projects/mobile-design-lib/src/components/avatar-with-badge/ds-avatar-with-badge.ts","../../../projects/mobile-design-lib/src/pages/whitelabel-demo.page.ts","../../../projects/mobile-design-lib/src/public-api.ts","../../../projects/mobile-design-lib/src/propbinder-mobile-design.ts"],"sourcesContent":["import { input, computed, Directive } from '@angular/core';\r\n\r\n/**\r\n * Content width preset values\r\n * - 'narrow' - 640px max width (reading content)\r\n * - 'standard' - 1024px max width (default)\r\n * - 'wide' - 1440px max width (dashboards)\r\n * - 'full' - 100% width (no max)\r\n */\r\nexport type ContentWidth = 'narrow' | 'standard' | 'wide' | 'full';\r\n\r\n/**\r\n * MobilePageBase\r\n * \r\n * Shared base class for mobile page components (ds-mobile-page-main, ds-mobile-page-details).\r\n * Provides consistent content width control across all page types.\r\n * \r\n * **Padding Strategy:**\r\n * - All pages use 20px horizontal padding globally\r\n * - For tappable lists, use negative margins (e.g., margin: 0 -8px) to create full-width sections\r\n * - This approach simplifies padding management and provides consistency\r\n * \r\n * @internal This is a base class and should not be used directly.\r\n */\r\n@Directive()\r\nexport abstract class MobilePageBase {\r\n /**\r\n * Maximum content width (desktop only)\r\n * \r\n * **Options:**\r\n * - `'narrow'` (640px) - For reading content, forms\r\n * - `'standard'` (1024px) - Default for most pages\r\n * - `'wide'` (1440px) - For dashboards, tables\r\n * - `'full'` - No max-width constraint\r\n * \r\n * **Note:** Only applies on desktop (>= 768px). Mobile is always full width.\r\n * \r\n * @default 'standard'\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Narrow reading layout -->\r\n * <ds-mobile-page-main title=\"Article\" contentWidth=\"narrow\">\r\n * \r\n * <!-- Wide dashboard -->\r\n * <ds-mobile-page-main title=\"Dashboard\" contentWidth=\"wide\">\r\n * ```\r\n */\r\n contentWidth = input<ContentWidth>('standard');\r\n\r\n /**\r\n * Resolved max-width value (computed)\r\n * Maps preset values to pixel values\r\n * \r\n * @internal\r\n */\r\n protected maxWidthValue = computed(() => {\r\n const w = this.contentWidth();\r\n \r\n const widthMap: Record<ContentWidth, string> = {\r\n 'narrow': '640px',\r\n 'standard': '1024px',\r\n 'wide': '1440px',\r\n 'full': '100%'\r\n };\r\n \r\n return widthMap[w];\r\n });\r\n}\r\n\r\n","import { \r\n Directive, \r\n Output, \r\n EventEmitter, \r\n HostListener, \r\n Input,\r\n OnDestroy \r\n} from '@angular/core';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileLongPressDirective\r\n * \r\n * A reusable directive for handling long press interactions on mobile devices.\r\n * Provides haptic feedback and prevents long press when touching interactive elements.\r\n * \r\n * Features:\r\n * - Configurable duration and movement threshold\r\n * - Automatic haptic feedback (with fallback to navigator.vibrate)\r\n * - Excludes interactive elements (buttons, links, inputs)\r\n * - Handles touchmove cancellation\r\n * - Context menu support (right-click on desktop)\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <div dsMobileLongPress (longPress)=\"handleLongPress()\">\r\n * Long press me\r\n * </div>\r\n * \r\n * <!-- Custom duration and threshold -->\r\n * <div \r\n * dsMobileLongPress \r\n * [longPressDuration]=\"800\"\r\n * [moveThreshold]=\"15\"\r\n * [excludeSelectors]=\"'button, a, .no-longpress'\"\r\n * (longPress)=\"showContextMenu()\">\r\n * Custom long press\r\n * </div>\r\n * ```\r\n */\r\n@Directive({\r\n selector: '[dsMobileLongPress]',\r\n standalone: true\r\n})\r\nexport class DsMobileLongPressDirective implements OnDestroy {\r\n /**\r\n * Duration in milliseconds to trigger long press\r\n * @default 500\r\n */\r\n @Input() longPressDuration = 500;\r\n\r\n /**\r\n * Maximum movement in pixels before canceling long press\r\n * @default 10\r\n */\r\n @Input() moveThreshold = 10;\r\n\r\n /**\r\n * CSS selectors to exclude from long press detection\r\n * @default 'button, a, input, select, textarea, [role=\"button\"]'\r\n */\r\n @Input() excludeSelectors = 'button, a, input, select, textarea, [role=\"button\"]';\r\n\r\n /**\r\n * Haptic feedback style (Light, Medium, Heavy)\r\n * @default ImpactStyle.Medium\r\n */\r\n @Input() hapticStyle: ImpactStyle = ImpactStyle.Medium;\r\n\r\n /**\r\n * Enable/disable haptic feedback\r\n * @default true\r\n */\r\n @Input() enableHaptics = true;\r\n\r\n /**\r\n * Emits when long press is triggered\r\n */\r\n @Output() longPress = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press starts (timer begins)\r\n */\r\n @Output() longPressStart = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press is cancelled\r\n */\r\n @Output() longPressCancel = new EventEmitter<void>();\r\n\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n\r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n handleTouchStart(event: TouchEvent): void {\r\n // Don't start long press if touching interactive elements\r\n const target = event.target as HTMLElement;\r\n if (target.closest(this.excludeSelectors)) {\r\n return;\r\n }\r\n\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n\r\n // Emit start event\r\n this.longPressStart.emit();\r\n\r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n\r\n // Haptic feedback for long press\r\n if (this.enableHaptics) {\r\n await this.triggerHaptics();\r\n }\r\n }, this.longPressDuration);\r\n }\r\n\r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n @HostListener('touchend', ['$event'])\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n \r\n if (!this.longPressTriggered) {\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n\r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n @HostListener('touchmove', ['$event'])\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n\r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n\r\n // Cancel long press if moved too far\r\n if (deltaX > this.moveThreshold || deltaY > this.moveThreshold) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n @HostListener('contextmenu', ['$event'])\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n\r\n /**\r\n * Trigger haptic feedback\r\n */\r\n private async triggerHaptics(): Promise<void> {\r\n try {\r\n await Haptics.impact({ style: this.hapticStyle });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n // Map haptic styles to vibration durations\r\n const vibrationMap = {\r\n [ImpactStyle.Light]: 30,\r\n [ImpactStyle.Medium]: 50,\r\n [ImpactStyle.Heavy]: 80\r\n };\r\n navigator.vibrate(vibrationMap[this.hapticStyle] || 50);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup on destroy\r\n */\r\n ngOnDestroy(): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n }\r\n}\r\n\r\n","import { Component, input, output, computed, signal, PLATFORM_ID, inject } from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { DsMobileLongPressDirective } from '../shared/directives/long-press.directive';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileListItemComponent\r\n * \r\n * A versatile, reusable list item component for mobile applications.\r\n * Supports both interactive and non-interactive modes with flexible content projection.\r\n * \r\n * Features:\r\n * - Interactive mode with click and long-press support\r\n * - Pseudo-element background extends 8px beyond bounds (no negative margins needed)\r\n * - Flexible content slots (leading, main, trailing)\r\n * - Optional structured inputs for common use cases (title, subtitle)\r\n * - Accessibility features (focus states, ARIA attributes)\r\n * - Disabled and loading states\r\n * \r\n * This component serves as the foundation for specialized list item types like posts,\r\n * notifications, messages, contacts, and other list content.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple structured usage -->\r\n * <ds-mobile-list-item\r\n * title=\"Document Title\"\r\n * subtitle=\"Supporting text\"\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\">\r\n * \r\n * <ds-icon content-leading name=\"document\" />\r\n * </ds-mobile-list-item>\r\n * \r\n * <!-- Flexible custom usage -->\r\n * <ds-mobile-list-item\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\"\r\n * (longPress)=\"showContextMenu()\">\r\n * \r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n * \r\n * <div content-main>\r\n * <h3>Custom Content</h3>\r\n * <p>Full control over layout and styling</p>\r\n * </div>\r\n * \r\n * <button content-trailing (click)=\"handleAction($event)\">\r\n * Action\r\n * </button>\r\n * </ds-mobile-list-item>\r\n * \r\n * <!-- Non-interactive read-only -->\r\n * <ds-mobile-list-item\r\n * title=\"Read-only Item\"\r\n * subtitle=\"No interaction\">\r\n * <ds-icon content-leading name=\"info\" />\r\n * </ds-mobile-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n hostDirectives: [\r\n {\r\n directive: DsMobileLongPressDirective,\r\n outputs: ['longPress']\r\n }\r\n ],\r\n host: {\r\n '[class.interactive]': 'interactive() && !disabled()',\r\n '[class.disabled]': 'disabled()',\r\n '[class.loading]': 'loading()',\r\n '[class.no-divider]': '!showDivider()',\r\n '[class.variant-feed]': 'variant() === \"feed\"',\r\n '[class.variant-detail]': 'variant() === \"detail\"',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '[attr.role]': 'interactive() ? \"button\" : null',\r\n '[attr.tabindex]': 'interactive() && !disabled() ? \"0\" : null',\r\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\r\n '[style.--leading-size]': 'leadingSize()',\r\n '[style.--interactive-offset]': 'interactiveOffset()',\r\n '[style.--divider-spacing]': 'dividerSpacing()',\r\n '(click)': 'handleClick($event)',\r\n '(keydown.enter)': 'handleKeyDown($event)',\r\n '(keydown.space)': 'handleKeyDown($event)',\r\n '(longPress)': 'handleLongPress()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: relative;\r\n padding: var(--item-padding-top, 12px) 0 var(--item-padding-bottom, 12px) 0;\r\n box-sizing: border-box;\r\n /* CSS variables defined at host level for use by children and pseudo-elements */\r\n --leading-size: 32px;\r\n --content-gap: 12px;\r\n --interactive-offset: 8px;\r\n }\r\n \r\n /* Divider line on host */\r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: calc(var(--leading-size) + var(--content-gap));\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default, #e5e5e5);\r\n z-index: 1;\r\n display: var(--divider-display, block);\r\n }\r\n \r\n .list-item-inner {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n gap: var(--content-gap);\r\n position: relative;\r\n }\r\n \r\n /* Pseudo-element for interactive background */\r\n :host(.interactive) .list-item-inner::before {\r\n content: '';\r\n position: absolute;\r\n top: calc(-1 * var(--interactive-offset));\r\n left: calc(-1 * var(--interactive-offset));\r\n right: calc(-1 * var(--interactive-offset));\r\n bottom: calc(-1 * var(--interactive-offset));\r\n background: var(--color-background-primary, #ffffff);\r\n border-radius: 16px;\r\n z-index: -1;\r\n pointer-events: none;\r\n }\r\n \r\n /* Interactive states */\r\n :host(.interactive) {\r\n cursor: pointer;\r\n }\r\n \r\n /* Hover state (desktop only) */\r\n @media (hover: hover) and (pointer: fine) {\r\n :host(.interactive):hover .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n }\r\n \r\n /* Active state */\r\n :host(.interactive):active .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n /* Focus visible for keyboard navigation */\r\n :host(.interactive):focus-visible {\r\n outline: none;\r\n }\r\n \r\n :host(.interactive):focus-visible .list-item-inner::before {\r\n outline: 2px solid var(--color-brand-primary, #5d5fef);\r\n outline-offset: 2px;\r\n }\r\n \r\n /* Disabled state */\r\n :host(.disabled) {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n }\r\n \r\n /* Loading state */\r\n :host(.loading) {\r\n pointer-events: none;\r\n }\r\n \r\n /* Variants */\r\n :host(.variant-detail) .list-item-inner {\r\n padding: 0;\r\n }\r\n \r\n :host(.variant-compact) .list-item-inner {\r\n gap: 8px;\r\n }\r\n \r\n /* Content slots */\r\n .content-leading {\r\n flex-shrink: 0;\r\n width: var(--leading-size);\r\n height: var(--leading-size);\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-start;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n /* Structured content styles */\r\n .structured-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .structured-subtitle {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n `],\r\n template: `\r\n <div class=\"list-item-inner\">\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n \r\n <div class=\"content-main\">\r\n @if (title()) {\r\n <h3 class=\"structured-title\">{{ title() }}</h3>\r\n }\r\n @if (subtitle()) {\r\n <p class=\"structured-subtitle\">{{ subtitle() }}</p>\r\n }\r\n \r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n \r\n <div class=\"content-trailing\">\r\n @if (interactive() && enableLongPress() && showDesktopMoreButton() && isDesktop()) {\r\n <ds-icon-button\r\n class=\"desktop-more-button\"\r\n icon=\"remixMoreFill\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleMoreButtonClick($event)\"\r\n aria-label=\"More options\">\r\n </ds-icon-button>\r\n }\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileListItemComponent {\r\n private platformId = inject(PLATFORM_ID);\r\n \r\n /**\r\n * Detect if viewport is desktop size\r\n * Use viewport width for breakpoint detection (show button on tablet and above)\r\n */\r\n isDesktop = signal<boolean>(false);\r\n \r\n constructor() {\r\n if (isPlatformBrowser(this.platformId)) {\r\n // Show button on tablet breakpoint and above (768px+)\r\n const isDesktopViewport = window.innerWidth >= 768;\r\n \r\n console.log('[ListItem] Desktop detection:', {\r\n innerWidth: window.innerWidth,\r\n isDesktopViewport\r\n });\r\n \r\n this.isDesktop.set(isDesktopViewport);\r\n \r\n // Listen for window resize to update detection\r\n window.addEventListener('resize', () => {\r\n const newIsDesktop = window.innerWidth >= 768;\r\n if (newIsDesktop !== this.isDesktop()) {\r\n console.log('[ListItem] Viewport changed, updating desktop detection:', newIsDesktop);\r\n this.isDesktop.set(newIsDesktop);\r\n }\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * CSS size value for the leading content area (e.g., '32px', '40px', '48px')\r\n * Defaults to '32px' for standard list item avatars/icons\r\n */\r\n leadingSize = input<string>('32px');\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related items\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the list item is interactive (clickable and long-pressable)\r\n * When true, adds interactive background, cursor pointer, and touch handlers\r\n */\r\n interactive = input<boolean>(false);\r\n \r\n /**\r\n * Whether the list item is disabled\r\n * Disables all interactions and reduces opacity\r\n */\r\n disabled = input<boolean>(false);\r\n \r\n /**\r\n * Whether the list item is in a loading state\r\n * Disables interactions but maintains full opacity\r\n */\r\n loading = input<boolean>(false);\r\n \r\n /**\r\n * Enable long-press interaction when interactive is true\r\n * Set to false to disable long-press but keep click\r\n */\r\n enableLongPress = input<boolean>(true);\r\n \r\n /**\r\n * Show \"more actions\" button on desktop for items with long-press enabled\r\n * Only visible on desktop (hover: hover) and when enableLongPress is true\r\n * Clicking this button triggers the same handler as long-press on mobile\r\n * @default true\r\n */\r\n showDesktopMoreButton = input<boolean>(true);\r\n \r\n /**\r\n * Offset distance for the interactive background pseudo-element\r\n * Extends the background beyond the content bounds\r\n * @default '8px'\r\n */\r\n interactiveOffset = input<string>('8px');\r\n \r\n /**\r\n * Optional structured title text\r\n * Provides a simple way to add title without custom markup\r\n */\r\n title = input<string>();\r\n \r\n /**\r\n * Optional structured subtitle text\r\n * Provides a simple way to add subtitle without custom markup\r\n */\r\n subtitle = input<string>();\r\n \r\n /**\r\n * Whether to show the divider line below the list item\r\n * Automatically hidden on last-child and detail variant\r\n * @default true\r\n */\r\n showDivider = input<boolean>(true);\r\n \r\n /**\r\n * Spacing around the divider (top and bottom padding)\r\n * @default '4px'\r\n */\r\n dividerSpacing = input<string>('4px');\r\n \r\n /**\r\n * Emits when the list item is clicked (if interactive and not disabled)\r\n */\r\n itemClick = output<void>();\r\n \r\n /**\r\n * Emits when the desktop more actions button is clicked\r\n * This is separate from longPress to give more control to parent components\r\n * Typically, you can use (longPress) for both mobile and desktop actions\r\n */\r\n moreButtonClick = output<Event>();\r\n \r\n /**\r\n * Track if long press was triggered to prevent click\r\n */\r\n private longPressTriggered = false;\r\n \r\n /**\r\n * Check if leading content slot has content\r\n * Always true to maintain consistent layout\r\n */\r\n hasLeadingContent = computed(() => true);\r\n \r\n /**\r\n * Check if trailing content slot has content\r\n * Always true to maintain consistent layout\r\n */\r\n hasTrailingContent = computed(() => true);\r\n \r\n /**\r\n * Handle click events\r\n */\r\n handleClick(event: Event): void {\r\n console.log('[ListItem] Click event fired', {\r\n interactive: this.interactive(),\r\n disabled: this.disabled(),\r\n loading: this.loading(),\r\n longPressTriggered: this.longPressTriggered,\r\n target: event.target\r\n });\r\n \r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n console.log('[ListItem] Click ignored - not interactive or disabled/loading');\r\n return;\r\n }\r\n \r\n // Don't emit click if it came from an interactive child element\r\n // (but not the host element itself)\r\n const target = event.target as HTMLElement;\r\n const closestInteractive = target.closest('button, a, input, select, textarea, [role=\"button\"]');\r\n \r\n // Check if the interactive element is a child, not the host itself\r\n if (closestInteractive && closestInteractive !== event.currentTarget) {\r\n console.log('[ListItem] Click ignored - came from interactive child:', closestInteractive);\r\n return;\r\n }\r\n \r\n if (!this.longPressTriggered) {\r\n console.log('[ListItem] Emitting itemClick');\r\n this.itemClick.emit();\r\n } else {\r\n console.log('[ListItem] Click ignored - long press was triggered');\r\n }\r\n \r\n this.longPressTriggered = false;\r\n }\r\n \r\n /**\r\n * Handle keyboard events (Enter/Space)\r\n */\r\n handleKeyDown(event: KeyboardEvent): void {\r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n return;\r\n }\r\n \r\n event.preventDefault();\r\n this.itemClick.emit();\r\n }\r\n \r\n /**\r\n * Handle long press events from the directive\r\n * Set the flag to prevent the subsequent click event\r\n */\r\n handleLongPress(): void {\r\n this.longPressTriggered = true;\r\n // Reset the flag after a short delay to allow for the next interaction\r\n setTimeout(() => {\r\n this.longPressTriggered = false;\r\n }, 100);\r\n }\r\n \r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation to prevent triggering itemClick\r\n * Emits moreButtonClick for parent components to handle\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n console.log('[ListItem] Desktop more button clicked');\r\n \r\n // Stop propagation to prevent triggering itemClick\r\n event.stopPropagation();\r\n event.preventDefault();\r\n \r\n // Emit the more button click event\r\n this.moreButtonClick.emit(event);\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { DsMobileListItemComponent } from '../list-item/ds-mobile-list-item';\r\n\r\n/**\r\n * DsMobileActionListItemComponent\r\n * \r\n * Specialized list item for action sheets and menus.\r\n * Wraps ds-mobile-list-item with action-specific styling:\r\n * - Vertically centered content\r\n * - Interactive by default\r\n * - No dividers (controlled per-item)\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-action-list-item\r\n * title=\"Edit\"\r\n * [showDivider]=\"true\"\r\n * (itemClick)=\"handleEdit()\">\r\n * <ds-icon content-leading name=\"remixEditLine\" size=\"20px\" />\r\n * </ds-mobile-action-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-action-list-item',\r\n standalone: true,\r\n imports: [DsMobileListItemComponent],\r\n template: `\r\n <ds-mobile-list-item\r\n [title]=\"title()\"\r\n [interactive]=\"true\"\r\n [enableLongPress]=\"false\"\r\n [showDivider]=\"showDivider()\"\r\n [disabled]=\"disabled()\"\r\n (itemClick)=\"itemClick.emit()\">\r\n \r\n <div content-leading>\r\n <ng-content select=\"[action-icon]\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `,\r\n styles: [`\r\n /* Center all content vertically for action items */\r\n :host ::ng-deep ds-mobile-list-item .list-item-inner {\r\n align-items: center;\r\n }\r\n \r\n /* Center icon within leading slot */\r\n :host ::ng-deep ds-mobile-list-item .content-leading {\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n /* Remove gap from content-main for single-line actions */\r\n :host ::ng-deep ds-mobile-list-item .content-main {\r\n gap: 0;\r\n justify-content: center;\r\n }\r\n `]\r\n})\r\nexport class DsMobileActionListItemComponent {\r\n /**\r\n * Action title text\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Whether to show divider below item\r\n * @default false\r\n */\r\n showDivider = input<boolean>(false);\r\n \r\n /**\r\n * Whether the action is disabled\r\n * @default false\r\n */\r\n disabled = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the action item is clicked\r\n */\r\n itemClick = output<void>();\r\n}\r\n\r\n","import { Component, Input, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileActionListItemComponent } from '../action-list-item/ds-mobile-action-list-item';\r\n\r\nexport interface ActionResult {\r\n action: string;\r\n}\r\n\r\nexport interface ActionItem {\r\n action: string;\r\n title: string;\r\n icon: string;\r\n destructive?: boolean;\r\n}\r\n\r\nexport interface ActionGroup {\r\n actions: ActionItem[];\r\n}\r\n\r\n/**\r\n * DsMobileActionsBottomSheetComponent\r\n * \r\n * Generic bottom sheet for displaying action lists.\r\n * Supports custom action groups or preset content actions (posts/comments).\r\n * Action groups are automatically separated by full-width dividers.\r\n * \r\n * @example Custom actions with auto-height (recommended to avoid cropping)\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * customActionGroups: [\r\n * {\r\n * actions: [\r\n * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },\r\n * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }\r\n * ]\r\n * },\r\n * {\r\n * actions: [\r\n * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }\r\n * ]\r\n * }\r\n * ]\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n * \r\n * const result = await sheet.onWillDismiss();\r\n * if (result.data?.action) {\r\n * // Handle the action\r\n * }\r\n * ```\r\n * \r\n * @example Preset content actions\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * isOwnContent: false\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-actions-bottom-sheet',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsMobileActionListItemComponent],\r\n template: `\r\n <div class=\"actions-sheet\">\r\n <!-- Actions List -->\r\n <div class=\"actions-list\">\r\n @for (group of actionGroups(); track $index; let isLast = $last) {\r\n <!-- Action Group -->\r\n <div class=\"action-group\">\r\n @for (actionItem of group.actions; track actionItem.action; let isLastInGroup = $last) {\r\n <ds-mobile-action-list-item\r\n [title]=\"actionItem.title\"\r\n [showDivider]=\"!isLastInGroup\"\r\n [class.destructive]=\"actionItem.destructive\"\r\n (itemClick)=\"selectAction(actionItem.action)\">\r\n <ds-icon \r\n action-icon \r\n [name]=\"actionItem.icon\" \r\n size=\"20px\" \r\n [class.destructive-icon]=\"actionItem.destructive\" />\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n \r\n <!-- Full-width divider between groups -->\r\n @if (!isLast) {\r\n <div class=\"action-group-divider\"></div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n .actions-sheet {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n padding-bottom: env(safe-area-inset-bottom, 0px);\r\n }\r\n \r\n /* Actions List */\r\n .actions-list {\r\n display: flex;\r\n flex-direction: column;\r\n padding-top: 16px; /* Only top padding for the container */\r\n }\r\n \r\n /* Action Group - padding on groups instead of list */\r\n .action-group {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 0 16px; /* Horizontal padding on each group */\r\n }\r\n \r\n /* Override default background color to transparent so hover state is visible */\r\n /* Need ::ng-deep because ds-mobile-list-item uses :host styles internally */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item {\r\n --color-background-primary: transparent;\r\n --color-background-neutral-primary-hover: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n /* Ensure the interactive background is visible */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .list-item-inner::before {\r\n z-index: 0 !important;\r\n }\r\n \r\n /* Ensure content is above the background */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-leading,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-main,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-trailing {\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n /* Hide divider on last list item using CSS variable */\r\n ds-mobile-action-list-item:last-of-type {\r\n --divider-display: none;\r\n }\r\n \r\n /* Destructive action styling */\r\n ds-mobile-action-list-item.destructive {\r\n --text-color-default-primary: var(--color-error-base, #ef4444);\r\n }\r\n \r\n .destructive-icon {\r\n color: var(--color-error-base, #ef4444);\r\n }\r\n \r\n /* Full-width divider between action groups */\r\n .action-group-divider {\r\n height: 1px;\r\n background: var(--color-border-subtle, #e5e5e5);\r\n margin: 8px 0;\r\n }\r\n `]\r\n})\r\nexport class DsMobileActionsBottomSheetComponent {\r\n /**\r\n * Custom action groups to display (overrides isOwnContent)\r\n */\r\n @Input() customActionGroups?: ActionGroup[];\r\n \r\n /**\r\n * Whether this content belongs to the current user (for preset content actions)\r\n */\r\n @Input() isOwnContent: boolean = false;\r\n \r\n /**\r\n * Computed action groups - uses custom groups if provided, otherwise falls back to preset content actions\r\n */\r\n actionGroups = computed<ActionGroup[]>(() => {\r\n // Use custom action groups if provided\r\n if (this.customActionGroups) {\r\n return this.customActionGroups;\r\n }\r\n \r\n // Otherwise fall back to preset content actions\r\n if (this.isOwnContent) {\r\n // Own content: Group 1 (Edit, Delete) + Group 2 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'edit',\r\n title: 'Rediger',\r\n icon: 'remixEditLine',\r\n destructive: false\r\n },\r\n {\r\n action: 'delete',\r\n title: 'Slet',\r\n icon: 'remixDeleteBinLine',\r\n destructive: true\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false\r\n }\r\n ]\r\n }\r\n ];\r\n } else {\r\n // Other users' content: Group 1 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false\r\n }\r\n ]\r\n }\r\n ];\r\n }\r\n });\r\n \r\n constructor(private modalController: ModalController) {}\r\n \r\n /**\r\n * Handle action selection and dismiss with result\r\n */\r\n selectAction(action: string): void {\r\n this.modalController.dismiss(\r\n { action } as ActionResult,\r\n 'select'\r\n );\r\n }\r\n}\r\n\r\n// Legacy exports for backwards compatibility\r\nexport { DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent };\r\nexport { DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent };\r\nexport type { ActionResult as PostActionResult };\r\nexport type { ActionResult as CommentActionResult };\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { ComponentRef } from '@angular/core';\r\n\r\n/**\r\n * Configuration options for the bottom sheet modal\r\n */\r\nexport interface BottomSheetOptions {\r\n /** The component to display in the bottom sheet */\r\n component: any;\r\n /** Component props to pass to the modal content */\r\n componentProps?: { [key: string]: any };\r\n /** Breakpoints for the bottom sheet (0-1 values representing percentage of screen) */\r\n breakpoints?: number[];\r\n /** Initial breakpoint to open the sheet at */\r\n initialBreakpoint?: number;\r\n /** Show/hide the drag handle */\r\n handle?: boolean;\r\n /** Custom CSS class for styling */\r\n cssClass?: string | string[];\r\n /** Whether backdrop dismisses the modal */\r\n backdropDismiss?: boolean;\r\n /** Backdrop opacity (0-1) */\r\n backdropOpacity?: number;\r\n /** Enable backdrop blur effect */\r\n backdropBlur?: boolean;\r\n /** Keyboard close behavior */\r\n keyboardClose?: boolean;\r\n /** Auto-height mode: sheet sizes to content instead of using fixed breakpoints */\r\n autoHeight?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileBottomSheetService\r\n * \r\n * Service for creating and managing Ionic 6 bottom sheet modals.\r\n * Based on the Ionic blog article: https://ionic.io/blog/5-examples-of-the-new-ionic-6-bottom-sheet-modal\r\n * \r\n * Features:\r\n * - Multiple breakpoints for snap-to positions\r\n * - Customizable initial height\r\n * - Optional drag handle\r\n * - Backdrop blur effect\r\n * - Custom styling support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private bottomSheet: DsMobileBottomSheetService) {}\r\n * \r\n * async openSheet() {\r\n * const sheet = await this.bottomSheet.create({\r\n * component: PostCreateComponent,\r\n * breakpoints: [0, 0.5, 0.9],\r\n * initialBreakpoint: 0.5,\r\n * handle: true\r\n * });\r\n * \r\n * const result = await sheet.onWillDismiss();\r\n * console.log('Sheet dismissed with:', result.data);\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileBottomSheetService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Create and present a bottom sheet modal\r\n * \r\n * @param options Configuration options for the bottom sheet\r\n * @returns Promise that resolves to the modal instance\r\n */\r\n async create(options: BottomSheetOptions): Promise<HTMLIonModalElement> {\r\n const {\r\n component,\r\n componentProps = {},\r\n breakpoints = [0, 0.5, 0.9],\r\n initialBreakpoint = 0.5,\r\n handle = true,\r\n cssClass = '',\r\n backdropDismiss = true,\r\n backdropOpacity,\r\n backdropBlur = false,\r\n keyboardClose = true,\r\n autoHeight = false\r\n } = options;\r\n\r\n // Build CSS classes array\r\n const cssClasses = ['ds-bottom-sheet'];\r\n if (backdropBlur) {\r\n cssClasses.push('ds-bottom-sheet--blur');\r\n }\r\n if (autoHeight) {\r\n cssClasses.push('auto-height');\r\n }\r\n if (typeof cssClass === 'string' && cssClass) {\r\n cssClasses.push(cssClass);\r\n } else if (Array.isArray(cssClass)) {\r\n cssClasses.push(...cssClass);\r\n }\r\n\r\n const modal = await this.modalController.create({\r\n component,\r\n componentProps,\r\n breakpoints: autoHeight ? undefined : breakpoints,\r\n initialBreakpoint: autoHeight ? undefined : initialBreakpoint,\r\n handle: autoHeight ? false : handle,\r\n cssClass: cssClasses,\r\n backdropDismiss,\r\n keyboardClose,\r\n showBackdrop: true,\r\n canDismiss: backdropDismiss,\r\n // Remove animation delay for instant appearance\r\n animated: true,\r\n enterAnimation: undefined, // Use default but we'll customize via CSS\r\n leaveAnimation: undefined,\r\n ...(backdropOpacity !== undefined && { \r\n cssClass: [...cssClasses, 'ds-bottom-sheet--custom-backdrop']\r\n })\r\n });\r\n\r\n // Apply custom backdrop opacity if specified\r\n if (backdropOpacity !== undefined) {\r\n modal.style.setProperty('--backdrop-opacity', backdropOpacity.toString());\r\n }\r\n\r\n // Add ESC key listener to dismiss the modal\r\n const escKeyHandler = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n modal.dismiss(undefined, 'escape');\r\n }\r\n };\r\n \r\n // Add listener when modal is presented\r\n modal.addEventListener('ionModalDidPresent', () => {\r\n document.addEventListener('keydown', escKeyHandler);\r\n });\r\n \r\n // Remove listener when modal is dismissed\r\n modal.addEventListener('ionModalDidDismiss', () => {\r\n document.removeEventListener('keydown', escKeyHandler);\r\n });\r\n\r\n await modal.present();\r\n \r\n // Don't wait - return immediately so component can try to focus\r\n // while still in user gesture context\r\n return modal;\r\n }\r\n\r\n /**\r\n * Dismiss all open modals\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal overlay\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","import { Component, signal, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController, IonHeader, IonToolbar, IonTitle, IonContent, IonButtons } from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { Camera, CameraResultType, CameraSource } from '@capacitor/camera';\r\nimport { StatusBar } from '@capacitor/status-bar';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobilePostCreateBottomSheetComponent\r\n * \r\n * Bottom sheet modal for creating new posts in the community feed.\r\n * This is the modal content that gets displayed in the bottom sheet.\r\n * Features Threads-inspired interface with rich text editing capabilities.\r\n * \r\n * Auto-focuses the textarea and brings up the keyboard when opened.\r\n * \r\n * Usage: Use with DsMobileBottomSheetService to present as a bottom sheet\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-create-bottom-sheet',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonButtons,\r\n DsButtonComponent,\r\n DsIconButtonComponent\r\n ],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n }\r\n\r\n /* ============================================\r\n HEADER\r\n ============================================ */\r\n \r\n ion-header {\r\n box-shadow: none;\r\n }\r\n\r\n ion-toolbar {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --border-width: 0 0 1px 0;\r\n --border-color: var(--border-color-default);\r\n --padding-top: 12px;\r\n --padding-bottom: 8px;\r\n --min-height: 56px;\r\n }\r\n\r\n ion-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 22px;\r\n letter-spacing: -0.4px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n\r\n ion-button {\r\n --color: var(--color-text-secondary, #737373);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n }\r\n\r\n /* Make Post button pill-shaped */\r\n ion-buttons[slot=\"end\"] ds-button {\r\n --border-radius: 100px;\r\n }\r\n \r\n ion-buttons[slot=\"end\"] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n \r\n /* Make Cancel button pill-shaped */\r\n ion-buttons[slot=\"start\"] ds-button {\r\n --border-radius: 100px;\r\n }\r\n \r\n ion-buttons[slot=\"start\"] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n\r\n /* ============================================\r\n CONTENT AREA\r\n ============================================ */\r\n \r\n ion-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n }\r\n\r\n .post-create-container {\r\n padding: 24px 16px 16px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n \r\n .post-composer {\r\n display: flex;\r\n gap: 12px;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-composer__main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .post-composer__header {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 32px;\r\n }\r\n \r\n .post-composer__username {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .post-composer__textarea {\r\n width: 100%;\r\n min-height: 60px;\r\n max-height: 400px;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n background: transparent;\r\n padding: 0;\r\n cursor: text;\r\n overflow-y: auto;\r\n /* Auto-resize as user types */\r\n field-sizing: content;\r\n }\r\n \r\n .post-composer__textarea::placeholder {\r\n color: var(--color-text-tertiary, #999999);\r\n }\r\n \r\n /* Visual focus indicator - helps users see the textarea is ready */\r\n .post-composer__textarea:focus {\r\n outline: none;\r\n }\r\n \r\n /* Subtle animation to draw attention when empty */\r\n @keyframes gentlePulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.6; }\r\n }\r\n \r\n .post-composer__textarea:not(:focus):empty + .focus-hint {\r\n animation: gentlePulse 2s ease-in-out 1;\r\n }\r\n \r\n .post-composer__actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding-top: 12px;\r\n }\r\n \r\n .post-composer__actions ds-icon-button::ng-deep button {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n }\r\n \r\n /* ============================================\r\n IMAGE PREVIEW\r\n ============================================ */\r\n \r\n .image-previews {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n margin-top: 12px;\r\n }\r\n \r\n .image-preview {\r\n position: relative;\r\n width: 96px;\r\n height: 96px;\r\n border-radius: 12px;\r\n overflow: visible;\r\n }\r\n \r\n .preview-image {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n border-radius: 12px;\r\n border: 1px solid var(--border-color-default);\r\n object-fit: cover;\r\n }\r\n \r\n .remove-image-btn {\r\n position: absolute;\r\n top: -8px;\r\n right: -8px;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 50%;\r\n background: rgba(0, 0, 0, 0.6);\r\n backdrop-filter: blur(8px);\r\n border: 2px solid white;\r\n color: white;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n padding: 0;\r\n }\r\n \r\n .remove-image-btn:hover {\r\n background: rgba(0, 0, 0, 0.8);\r\n transform: scale(1.05);\r\n }\r\n \r\n .remove-image-btn:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n /* ============================================\r\n MOBILE OPTIMIZATIONS\r\n ============================================ */\r\n \r\n @media (max-width: 768px) {\r\n .post-create-container {\r\n padding: 12px 16px 24px;\r\n }\r\n\r\n .post-composer__textarea {\r\n min-height: 60px;\r\n max-height: 300px;\r\n /* Make tap target larger on mobile */\r\n padding: 8px;\r\n margin: -8px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <!-- Header with cancel and post buttons -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <ion-buttons slot=\"start\">\r\n <ds-button\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleCancel()\">\r\n Annuller\r\n </ds-button>\r\n </ion-buttons>\r\n <ion-title>{{ modalTitle() }}</ion-title>\r\n <ion-buttons slot=\"end\">\r\n <ds-button\r\n variant=\"primary\"\r\n size=\"sm\"\r\n [disabled]=\"!canPost()\"\r\n (clicked)=\"handlePost()\">\r\n {{ submitButtonLabel() }}\r\n </ds-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content -->\r\n <ion-content>\r\n <div class=\"post-create-container\">\r\n <div class=\"post-composer\">\r\n <div class=\"post-composer__main\">\r\n <textarea\r\n #textareaInput\r\n class=\"post-composer__textarea\"\r\n [(ngModel)]=\"postContent\"\r\n [placeholder]=\"placeholder()\"\r\n [readonly]=\"isReadonly\"\r\n (input)=\"handleInput()\"\r\n (focus)=\"handleFocus()\"\r\n inputmode=\"text\"\r\n enterkeyhint=\"done\"\r\n rows=\"1\">\r\n </textarea>\r\n \r\n <!-- Image Previews -->\r\n @if (selectedImages().length > 0) {\r\n <div class=\"image-previews\">\r\n @for (image of selectedImages(); track image; let i = $index) {\r\n <div class=\"image-preview\">\r\n <img [src]=\"image\" alt=\"Selected image\" class=\"preview-image\" />\r\n <button \r\n class=\"remove-image-btn\" \r\n (click)=\"handleRemoveImage(i)\"\r\n type=\"button\"\r\n aria-label=\"Fjern billede\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M12 4L4 12M4 4L12 12\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n <div class=\"post-composer__actions\">\r\n <ds-icon-button\r\n icon=\"remixImageLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddImage()\"\r\n aria-label=\"Tilføj billede\">\r\n </ds-icon-button>\r\n <ds-icon-button\r\n icon=\"remixAttachmentLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddAttachment()\"\r\n aria-label=\"Tilføj vedhæftning\">\r\n </ds-icon-button>\r\n \r\n <!-- Hidden file input for file selection -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"*/*\"\r\n multiple\r\n (change)=\"handleFileSelect($event)\"\r\n style=\"display: none;\"\r\n aria-hidden=\"true\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePostCreateBottomSheetComponent implements AfterViewInit, OnInit {\r\n @ViewChild('textareaInput') textareaInput?: ElementRef<HTMLTextAreaElement>;\r\n @ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;\r\n \r\n // Optional input to control auto-focus behavior\r\n autoFocus = true;\r\n \r\n // Control readonly state for keyboard trick\r\n isReadonly = true;\r\n \r\n // Edit mode properties - can be set via componentProps\r\n isEditMode = false;\r\n postId?: string;\r\n initialContent = '';\r\n \r\n postContent = '';\r\n selectedImages = signal<string[]>([]);\r\n username = signal('Lars Mikkelsen');\r\n placeholder = signal(\"Hvad er nyt?\");\r\n modalTitle = signal('Nyt opslag');\r\n submitButtonLabel = signal('Slå op');\r\n \r\n constructor(\r\n private modalController: ModalController,\r\n private elementRef: ElementRef\r\n ) {}\r\n \r\n /**\r\n * Ensure toolbar doesn't have unnecessary padding\r\n * Modal is already positioned below status bar, so no extra safe area needed\r\n */\r\n private applySafeAreaToToolbar(): void {\r\n try {\r\n const hostElement = this.elementRef?.nativeElement;\r\n if (hostElement) {\r\n const header = hostElement.querySelector('ion-header');\r\n if (header) {\r\n const toolbar = header.querySelector('ion-toolbar');\r\n if (toolbar) {\r\n const toolbarElement = toolbar as HTMLElement;\r\n // Ensure toolbar uses standard padding (no safe area since modal is already offset)\r\n toolbarElement.style.setProperty('--padding-top', '12px', 'important');\r\n toolbarElement.style.setProperty('--min-height', '56px', 'important');\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n console.log('[SafeArea] Failed to apply to toolbar:', e);\r\n }\r\n }\r\n \r\n ngOnInit(): void {\r\n // Initialize edit mode if provided\r\n if (this.isEditMode && this.initialContent) {\r\n this.postContent = this.initialContent;\r\n this.modalTitle.set('Rediger opslag');\r\n this.submitButtonLabel.set('Gem');\r\n }\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Apply safe area padding immediately to prevent corruption\r\n this.applySafeAreaToToolbar();\r\n \r\n // Auto-resize textarea if there's initial content (edit mode)\r\n if (this.postContent && this.textareaInput) {\r\n setTimeout(() => {\r\n this.resizeTextarea();\r\n }, 0);\r\n }\r\n \r\n // Try to focus IMMEDIATELY - no delay\r\n // This maximizes our chance of being in user gesture context\r\n if (this.autoFocus && this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Remove readonly immediately\r\n this.isReadonly = false;\r\n \r\n // Try focusing with minimal delay\r\n setTimeout(() => {\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // iOS sometimes needs a second attempt\r\n setTimeout(() => {\r\n textarea.focus();\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }, 100);\r\n }, 10);\r\n }\r\n }\r\n \r\n /**\r\n * Ionic lifecycle hook - called when modal enters view\r\n * At 95% height, this acts more like a page than a modal\r\n * which might allow keyboard to open\r\n */\r\n ionViewDidEnter(): void {\r\n // Resize textarea in case initial attempt didn't work\r\n if (this.postContent && this.textareaInput) {\r\n this.resizeTextarea();\r\n }\r\n \r\n // Final focus attempt when view fully enters\r\n if (this.autoFocus && this.textareaInput) {\r\n this.isReadonly = false;\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Try to focus as if this was a page navigation\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // Set cursor position\r\n const length = textarea.value.length;\r\n textarea.setSelectionRange(length, length);\r\n }\r\n }\r\n \r\n handleFocus(): void {\r\n // When user focuses (or we focus programmatically), remove readonly\r\n this.isReadonly = false;\r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }\r\n \r\n handleInput(): void {\r\n this.resizeTextarea();\r\n }\r\n \r\n /**\r\n * Auto-resize textarea based on content\r\n */\r\n private resizeTextarea(): void {\r\n if (this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n // Reset height to auto to get the correct scrollHeight\r\n textarea.style.height = 'auto';\r\n // Set height based on content, respecting min/max from CSS\r\n textarea.style.height = Math.min(textarea.scrollHeight, 400) + 'px';\r\n }\r\n }\r\n \r\n canPost(): boolean {\r\n return this.postContent.trim().length > 0 || this.selectedImages().length > 0;\r\n }\r\n \r\n async handleCancel(): Promise<void> {\r\n if (this.postContent.trim().length > 0 || this.selectedImages().length > 0) {\r\n // Show confirmation\r\n const confirmed = confirm('Kassér dette opslag?');\r\n if (confirmed) {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n } else {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n }\r\n \r\n async handlePost(): Promise<void> {\r\n if (!this.canPost()) return;\r\n \r\n if (this.isEditMode) {\r\n console.log('Updating post:', this.postId, this.postContent);\r\n } else {\r\n console.log('Creating post:', this.postContent, 'with images:', this.selectedImages().length);\r\n }\r\n \r\n // Pass the post content, images, and edit info back to the parent\r\n await this.modalController.dismiss(\r\n { \r\n content: this.postContent,\r\n images: this.selectedImages(),\r\n timestamp: new Date(),\r\n isEdit: this.isEditMode,\r\n postId: this.postId\r\n },\r\n 'post'\r\n );\r\n }\r\n \r\n async handleAddImage(): Promise<void> {\r\n console.log('Add image button clicked');\r\n \r\n // Re-apply safe area padding before opening camera (preventive)\r\n // This ensures the value is locked in before iOS corrupts it\r\n this.applySafeAreaToToolbar();\r\n \r\n try {\r\n console.log('Requesting photo from library...');\r\n \r\n const image = await Camera.getPhoto({\r\n quality: 90,\r\n allowEditing: false,\r\n resultType: CameraResultType.Uri,\r\n source: CameraSource.Photos, // Only show photo library, not camera\r\n });\r\n\r\n console.log('Photo selected successfully:', image);\r\n \r\n // Add the image path to the array\r\n if (image.webPath) {\r\n this.selectedImages.update(images => [...images, image.webPath!]);\r\n console.log('Image added to preview:', image.webPath);\r\n }\r\n \r\n // Re-apply safe area padding immediately after returning\r\n // Since we're using fixed values, this won't cause flickering\r\n requestAnimationFrame(() => {\r\n this.applySafeAreaToToolbar();\r\n });\r\n \r\n // Restore StatusBar configuration (background task)\r\n this.restoreStatusBar();\r\n \r\n } catch (error) {\r\n console.error('Photo selection error:', error);\r\n // Only show alert for non-cancellation errors\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const errorMessage = (error as any).message;\r\n if (!errorMessage.includes('cancel')) {\r\n alert(`Error selecting photo: ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Restore StatusBar configuration (background task)\r\n * Safe area padding is now handled preventively via applySafeAreaToToolbar()\r\n */\r\n private restoreStatusBar(): void {\r\n setTimeout(async () => {\r\n try {\r\n await StatusBar.setBackgroundColor({ color: '#221a4c' });\r\n await StatusBar.setOverlaysWebView({ overlay: false });\r\n } catch (e) {\r\n // StatusBar API not available, ignore\r\n }\r\n }, 0);\r\n }\r\n \r\n handleRemoveImage(index: number): void {\r\n console.log('Removing image at index:', index);\r\n this.selectedImages.update(images => images.filter((_, i) => i !== index));\r\n }\r\n \r\n handleAddAttachment(): void {\r\n console.log('Add attachment button clicked');\r\n // Trigger the hidden file input\r\n if (this.fileInput) {\r\n this.fileInput.nativeElement.click();\r\n }\r\n }\r\n \r\n handleFileSelect(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const files = input.files;\r\n \r\n if (!files || files.length === 0) {\r\n console.log('No files selected');\r\n return;\r\n }\r\n \r\n console.log('Files selected:', files.length);\r\n \r\n // Process each selected file\r\n Array.from(files).forEach(file => {\r\n console.log('File:', file.name, file.type, file.size);\r\n \r\n // Create a data URL for preview (for images and other files)\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const result = e.target?.result as string;\r\n if (result) {\r\n // Add to selectedImages array for preview\r\n this.selectedImages.update(images => [...images, result]);\r\n console.log('File added to preview:', file.name);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n \r\n // Reset the input so the same file can be selected again\r\n input.value = '';\r\n }\r\n}\r\n\r\n","import { Component, input, output, HostListener, ElementRef, ViewChild, AfterViewInit, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { \r\n IonHeader, \r\n IonToolbar, \r\n IonTitle,\r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent,\r\n Platform,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\nimport { DsMobileActionsBottomSheetComponent, ActionResult } from '../bottom-sheet';\r\n\r\n/**\r\n * DsMobilePageMainComponent\r\n * \r\n * A complete mobile page layout for main/tab pages with:\r\n * - Fixed header with logomark + title + avatar\r\n * - Purple expandable header section (scrolls with content)\r\n * - White rounded content wrapper\r\n * - Pull-to-refresh support\r\n * - Auto scroll title fade-in\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple page -->\r\n * <ds-mobile-page-main\r\n * title=\"Inquiries\"\r\n * [avatarInitials]=\"'JD'\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n * \r\n * <!-- Page with custom header content -->\r\n * <ds-mobile-page-main\r\n * title=\"Home\"\r\n * headerTitle=\"Welcome, Lars\"\r\n * headerSubtitle=\"Your rental property at a glance.\"\r\n * [avatarInitials]=\"'L'\">\r\n * \r\n * <div header-content class=\"property-tiles\">\r\n * <!-- Custom header content like tiles -->\r\n * </div>\r\n * \r\n * <div class=\"page-content\">\r\n * <!-- Main page content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-main',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-page-main.css'],\r\n template: `\r\n <!-- Fixed header at top -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-home\">\r\n <!-- Propbinder Logomark -->\r\n <svg class=\"logomark\" width=\"36\" height=\"32\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n \r\n <!-- Title - fades in on scroll -->\r\n <ion-title class=\"header-home__title\">{{ title() }}</ion-title>\r\n \r\n <!-- Avatar -->\r\n <div class=\"header-home__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n (click)=\"handleAvatarClick()\"\r\n style=\"cursor: pointer;\"\r\n />\r\n </div>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content with expandable header -->\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n <!-- Condensed header for Ionic scroll effects -->\r\n @if (showCondensedHeader()) {\r\n <ion-header collapse=\"condense\">\r\n <ion-toolbar>\r\n <ion-title size=\"large\">{{ title() }}</ion-title>\r\n </ion-toolbar>\r\n </ion-header>\r\n }\r\n\r\n <!-- Pull to refresh (only on native iOS/Android) -->\r\n @if (showRefresh() && isNativePlatform()) {\r\n <ion-refresher \r\n slot=\"fixed\" \r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\" \r\n [pullMin]=\"80\" \r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"remixArrowDownS\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <!-- Expandable header section (purple background) -->\r\n <div class=\"header-expandable\">\r\n <div class=\"header-expandable-inner\">\r\n <div class=\"header-expandable__text\">\r\n <h1 class=\"header-expandable__title\">{{ headerTitle() || title() }}</h1>\r\n @if (headerSubtitle()) {\r\n <p class=\"header-expandable__subtitle\">{{ headerSubtitle() }}</p>\r\n }\r\n </div>\r\n \r\n <!-- Slot for custom header content (e.g., property tiles) -->\r\n <ng-content select=\"[header-content]\"></ng-content>\r\n </div>\r\n </div>\r\n\r\n <!-- Content wrapper -->\r\n <div class=\"content-wrapper\">\r\n <div class=\"content-inner\">\r\n <!-- Main page content -->\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePageMainComponent extends MobilePageBase implements AfterViewInit {\r\n @ViewChild(IonContent) ionContent?: IonContent;\r\n \r\n // Platform detection\r\n private platform = inject(Platform);\r\n private modalController = inject(ModalController);\r\n private router = inject(Router);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n \r\n // Inputs - Title\r\n title = input.required<string>(); // For fixed header title\r\n headerTitle = input<string>(''); // Optional different title for expandable header\r\n headerSubtitle = input<string>('');\r\n \r\n // Inputs - Avatar\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n avatarInitials = input<string>('U');\r\n avatarSrc = input<string>('');\r\n avatarIconName = input<string>('remixUser3Line');\r\n \r\n // Inputs - Features\r\n showRefresh = input<boolean>(true);\r\n showCondensedHeader = input<boolean>(true);\r\n scrollThreshold = input<number>(160); // Pixels to scroll before title appears\r\n headerFadeDistance = input<number>(150); // Distance over which header fades out\r\n \r\n // Outputs\r\n avatarClick = output<void>();\r\n refresh = output<any>();\r\n scroll = output<any>();\r\n \r\n constructor(private elementRef: ElementRef) {\r\n super();\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial setup if needed\r\n }\r\n \r\n /**\r\n * Handle avatar click - opens profile actions bottom sheet\r\n */\r\n async handleAvatarClick(): Promise<void> {\r\n console.log('Avatar clicked - opening profile bottom sheet');\r\n \r\n // Emit the event for any parent listeners\r\n this.avatarClick.emit();\r\n \r\n const sheet = await this.modalController.create({\r\n component: DsMobileActionsBottomSheetComponent,\r\n componentProps: {\r\n customActionGroups: [\r\n {\r\n actions: [\r\n {\r\n action: 'profile',\r\n title: 'Min profil',\r\n icon: 'remixUser3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'settings',\r\n title: 'Indstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'whitelabel-demo',\r\n title: 'Whitelabel Demo',\r\n icon: 'remixPaletteLine',\r\n destructive: false\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'logout',\r\n title: 'Log ud',\r\n icon: 'remixLogoutBoxLine',\r\n destructive: true\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n // Auto-height: no breakpoints, no handle\r\n cssClass: 'ds-bottom-sheet auto-height'\r\n });\r\n \r\n await sheet.present();\r\n \r\n const result = await sheet.onWillDismiss<ActionResult>();\r\n if (result.data?.action) {\r\n console.log('Profile action selected:', result.data.action);\r\n \r\n switch (result.data.action) {\r\n case 'logout':\r\n console.log('Logging out...');\r\n // TODO: Implement logout logic\r\n break;\r\n case 'profile':\r\n console.log('Opening profile...');\r\n // TODO: Navigate to profile page\r\n break;\r\n case 'settings':\r\n console.log('Opening settings...');\r\n // TODO: Navigate to settings page\r\n break;\r\n case 'whitelabel-demo':\r\n console.log('Opening whitelabel demo...');\r\n this.router.navigate(['/whitelabel-demo']);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Handle scroll events\r\n * - Shows title in fixed header when scrolled past threshold\r\n * - Fades out expandable header content based on scroll position\r\n * - Emits scroll event for custom handling\r\n */\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop;\r\n const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');\r\n const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');\r\n \r\n // Show title in fixed header when scrolled past threshold\r\n if (scrollTop > this.scrollThreshold()) {\r\n header?.classList.add('header-scrolled');\r\n } else {\r\n header?.classList.remove('header-scrolled');\r\n }\r\n \r\n // Fade out header-expandable content based on scroll\r\n if (headerExpandable) {\r\n const fadeDistance = this.headerFadeDistance();\r\n const fadeProgress = Math.min(scrollTop / fadeDistance, 1);\r\n \r\n // Calculate opacity (1 to 0)\r\n const opacity = 1 - fadeProgress;\r\n \r\n // Calculate transform (0px to -20px upward)\r\n const translateY = fadeProgress * -20;\r\n \r\n // Apply styles\r\n headerExpandable.style.opacity = opacity.toString();\r\n headerExpandable.style.transform = `translateY(${translateY}px)`;\r\n }\r\n \r\n this.scroll.emit(event);\r\n }\r\n \r\n /**\r\n * Handle pull-to-refresh\r\n * Emits refresh event - parent should call event.target.complete()\r\n */\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n this.refresh.emit(event);\r\n }\r\n}\r\n\r\n","import { Component, input, output, ElementRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { IonHeader, IonToolbar, IonContent } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\n\r\n/**\r\n * DsMobilePageDetailsComponent\r\n * \r\n * A mobile page layout for detail/drill-down pages with:\r\n * - Back button header (mobile + desktop variants)\r\n * - White background content area\r\n * - Responsive padding\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple detail page -->\r\n * <ds-mobile-page-details\r\n * title=\"Property Details\"\r\n * (back)=\"goBack()\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * \r\n * <!-- With default back route -->\r\n * <ds-mobile-page-details\r\n * title=\"Invoice Details\"\r\n * backRoute=\"/invoices\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-details',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonContent,\r\n DsIconComponent\r\n ],\r\n styleUrls: ['./ds-mobile-page-details.css'],\r\n template: `\r\n <!-- Mobile header - hidden on desktop -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-back\">\r\n <button class=\"back-button\" (click)=\"handleBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftLine\" size=\"24px\" />\r\n </button>\r\n <h1 class=\"header-title\">{{ title() }}</h1>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <ion-content>\r\n <!-- Desktop header above content -->\r\n <div class=\"desktop-header\">\r\n <button class=\"back-button\" (click)=\"handleBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftLine\" size=\"24px\" />\r\n </button>\r\n <h1>{{ title() }}</h1>\r\n </div>\r\n\r\n <!-- Content area -->\r\n <div class=\"detail-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePageDetailsComponent extends MobilePageBase {\r\n // Inputs\r\n title = input.required<string>();\r\n backRoute = input<string>(''); // Optional default back route\r\n \r\n // Outputs\r\n back = output<void>();\r\n \r\n constructor(\r\n private navCtrl: NavController,\r\n private elementRef: ElementRef\r\n ) {\r\n super();\r\n }\r\n \r\n /**\r\n * Handle back navigation\r\n * \r\n * By default, navigates using the provided backRoute or browser back.\r\n * Parent components can listen to the (back) event to override this behavior.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default behavior: uses backRoute or browser back -->\r\n * <ds-mobile-page-details \r\n * title=\"Details\" \r\n * backRoute=\"/home\">\r\n * </ds-mobile-page-details>\r\n * \r\n * <!-- Custom behavior: parent handles navigation -->\r\n * <ds-mobile-page-details \r\n * title=\"Details\"\r\n * (back)=\"customBackHandler()\">\r\n * </ds-mobile-page-details>\r\n * ```\r\n */\r\n handleBack(): void {\r\n // Add class to trigger reverse animation\r\n this.elementRef.nativeElement.classList.add('navigating-back');\r\n \r\n // Emit event for parent to optionally handle\r\n this.back.emit();\r\n \r\n // Default behavior: navigate using backRoute or browser back\r\n if (this.backRoute()) {\r\n this.navCtrl.navigateBack(this.backRoute());\r\n } else {\r\n this.navCtrl.back();\r\n }\r\n }\r\n}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileContentComponent\r\n * \r\n * Main content container for mobile pages with flexible layout options.\r\n * Provides consistent spacing and layout patterns.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default: stacked layout -->\r\n * <ds-mobile-content>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * </ds-mobile-content>\r\n * \r\n * <!-- Grid layout -->\r\n * <ds-mobile-content layout=\"grid-2\">\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * </ds-mobile-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[class.layout-stacked]': 'layout() === \"stacked\"',\r\n '[class.layout-grid-2]': 'layout() === \"grid-2\"',\r\n '[class.layout-grid-3]': 'layout() === \"grid-3\"'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 32px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n \r\n /* Grid layouts */\r\n :host.layout-grid-2 {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 16px;\r\n }\r\n \r\n :host.layout-grid-3 {\r\n display: grid;\r\n grid-template-columns: repeat(3, 1fr);\r\n gap: 16px;\r\n }\r\n \r\n @media (max-width: 768px) {\r\n :host.layout-grid-2,\r\n :host.layout-grid-3 {\r\n grid-template-columns: 1fr;\r\n }\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class DsMobileContentComponent {\r\n /**\r\n * Layout mode for content sections\r\n * - 'stacked' - Vertical stack with 32px gap (default)\r\n * - 'grid-2' - 2 column grid\r\n * - 'grid-3' - 3 column grid (stacks on mobile)\r\n */\r\n layout = input<'stacked' | 'grid-2' | 'grid-3'>('stacked');\r\n}\r\n\r\n/**\r\n * DsMobileContentSectionComponent\r\n * \r\n * Section within mobile content with optional header.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-content-section>\r\n * <section-header width=\"half\"></section-header>\r\n * <content-row>\r\n * <div class=\"grey-box\"></div>\r\n * </content-row>\r\n * </ds-mobile-content-section>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-content-section',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"section-header\" />\r\n <ng-content />\r\n `\r\n})\r\nexport class DsMobileContentSectionComponent {}\r\n\r\n/**\r\n * SectionHeaderComponent\r\n * \r\n * Semantic placeholder header for content sections.\r\n * Used for prototyping/placeholders.\r\n */\r\n@Component({\r\n selector: 'section-header',\r\n standalone: true,\r\n host: {\r\n '[class.w-half]': 'width() === \"half\"',\r\n '[class.w-third]': 'width() === \"third\"',\r\n '[class.w-full]': 'width() === \"full\"'\r\n },\r\n styles: [`\r\n :host {\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-background-neutral-tertiary);\r\n display: block;\r\n }\r\n \r\n :host.w-half { width: 50%; }\r\n :host.w-third { width: 33%; }\r\n :host.w-full { width: 100%; }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class SectionHeaderComponent {\r\n /** Width of the header placeholder */\r\n width = input<'half' | 'third' | 'full'>('half');\r\n}\r\n\r\n/**\r\n * ContentRowComponent\r\n * \r\n * Horizontal row container for content items.\r\n */\r\n@Component({\r\n selector: 'content-row',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class ContentRowComponent {}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileHeaderContentComponent\r\n * \r\n * Container for header content tiles - displays tiles in a responsive grid.\r\n * Used within the expandable header section of mobile pages to show\r\n * summary information like property details, statistics, etc.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content header-content>\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Area</tile-label>\r\n * <tile-value>120 m²</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * </ds-mobile-header-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 12px;\r\n }\r\n \r\n @media (min-width: 768px) {\r\n :host {\r\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\r\n }\r\n }\r\n `],\r\n template: `<ng-content select=\"ds-mobile-header-content-tile\" />`\r\n})\r\nexport class DsMobileHeaderContentComponent {}\r\n\r\n/**\r\n * DsMobileHeaderContentTileComponent\r\n * \r\n * Individual tile for displaying summary information in the header.\r\n * Styled with purple background to match the mobile header theme.\r\n * \r\n * Must contain:\r\n * - `<tile-icon>` - Icon container (optional)\r\n * - `<tile-content>` - Label and value container\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" size=\"20px\" color=\"#DFE4FF\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Rooms</tile-label>\r\n * <tile-value>3 rooms</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content-tile',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n background: rgba(255, 255, 255, 0.05);\r\n border: 1px solid rgba(255, 255, 255, 0.1);\r\n border-radius: 12px;\r\n padding: 12px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-icon\" />\r\n <ng-content select=\"tile-content\" />\r\n `\r\n})\r\nexport class DsMobileHeaderContentTileComponent {}\r\n\r\n/**\r\n * TileIconComponent\r\n * \r\n * Semantic slot for tile icon with dark purple background.\r\n * Use within `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-icon',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n background: var(--color-brand-secondary);\r\n border-radius: 8px;\r\n width: 32px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileIconComponent {}\r\n\r\n/**\r\n * TileContentComponent\r\n * \r\n * Semantic slot for tile content containing label and value.\r\n * Use within `ds-mobile-header-content-tile`.\r\n * \r\n * Contains:\r\n * - `<tile-label>` - Small label text\r\n * - `<tile-value>` - Large value text\r\n */\r\n@Component({\r\n selector: 'tile-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n ::ng-deep tile-label {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(255, 255, 255, 0.8);\r\n display: block;\r\n }\r\n \r\n ::ng-deep tile-value {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: #ffffff;\r\n display: block;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-label\" />\r\n <ng-content select=\"tile-value\" />\r\n `\r\n})\r\nexport class TileContentComponent {}\r\n\r\n/**\r\n * TileLabelComponent\r\n * \r\n * Label text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-label',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(255, 255, 255, 0.8);\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileLabelComponent {}\r\n\r\n/**\r\n * TileValueComponent\r\n * \r\n * Value text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-value',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: #ffffff;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileValueComponent {}\r\n\r\n","import { Component, input, output, signal, model } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobilePostCardComponent\r\n * \r\n * Individual post card for community feed and post details.\r\n * Displays user posts with avatar, content, media, and action buttons.\r\n * Follows Threads-inspired design with clean layout and interactions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-post-card\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [clickable]=\"true\"\r\n * (postClick)=\"openPost()\">\r\n * \r\n * <post-content>\r\n * <post-text>This is a sample post...</post-text>\r\n * </post-content>\r\n * \r\n * <post-actions>\r\n * <action-like [active]=\"true\" count=\"42\" />\r\n * <action-comment count=\"12\" />\r\n * <action-share />\r\n * </post-actions>\r\n * </ds-mobile-post-card>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-card',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '[class.variant-feed]': 'variant() === \"feed\"',\r\n '[class.variant-detail]': 'variant() === \"detail\"',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '(click)': 'handlePostClick($event)',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-primary, #ffffff);\r\n padding: 8px;\r\n gap: 8px;\r\n transition: all 0.2s ease;\r\n position: relative;\r\n border-radius: 16px;\r\n margin-bottom: 8px;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n left: 52px;\r\n right: 8px;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:active {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n :host.variant-detail {\r\n padding: 0;\r\n margin-bottom: 8px;\r\n }\r\n \r\n :host.variant-detail::after {\r\n display: none;\r\n }\r\n \r\n :host.variant-compact {\r\n padding: 8px;\r\n gap: 8px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .post-header {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n /* Author styles imported from mobile-common.css */\r\n \r\n .menu-slot {\r\n margin-left: auto;\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n bottom: -6px;\r\n right: -6px;\r\n width: 20px;\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-brand-secondary, #5d5fef);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: 2px solid var(--color-background-primary, #ffffff);\r\n }\r\n \r\n .avatar-badge svg {\r\n width: 10px;\r\n position: relative;\r\n top: 1px;\r\n fill: white;\r\n }\r\n `],\r\n template: `\r\n <div class=\"post-header\">\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n @if (showBadge()) {\r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n }\r\n </div>\r\n \r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ authorName() }}</div>\r\n <div class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</div>\r\n </div>\r\n \r\n <div class=\"menu-slot\">\r\n <ng-content select=\"post-menu\" />\r\n </div>\r\n </div>\r\n \r\n <ng-content select=\"post-content\" />\r\n <ng-content select=\"post-actions\" />\r\n `\r\n})\r\nexport class DsMobilePostCardComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2h ago\", \"1d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Show badge on avatar (e.g., for property managers)\r\n */\r\n showBadge = input<boolean>(false);\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related posts\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the post card is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the post card is clicked (if clickable)\r\n */\r\n postClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when the post card is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n \r\n handlePostClick(event: Event): void {\r\n if (this.clickable()) {\r\n this.postClick.emit();\r\n }\r\n }\r\n \r\n handleCommentClick(): void {\r\n this.commentClick.emit();\r\n }\r\n \r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n // Don't start long press if touching action buttons or interactive elements\r\n const target = event.target as HTMLElement;\r\n if (target.closest('post-actions, action-like, action-comment, action-share, button, a, img')) {\r\n return;\r\n }\r\n \r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n \r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n \r\n // Haptic feedback for long press\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n \r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n \r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n \r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n/**\r\n * PostContentComponent\r\n * \r\n * Main content section of the post.\r\n * \r\n * Contains:\r\n * - `<post-text>` - Text content\r\n * - `<post-media>` - Optional images/videos\r\n * - `<post-attachments>` - Optional file attachments\r\n */\r\n@Component({\r\n selector: 'post-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n :host:not(.no-indent) {\r\n padding-left: 44px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"post-text\" />\r\n <ng-content select=\"post-media\" />\r\n <ng-content select=\"ds-mobile-inline-photo\" />\r\n <ng-content select=\"post-attachments\" />\r\n `\r\n})\r\nexport class PostContentComponent {}\r\n\r\n/**\r\n * PostTextComponent\r\n * \r\n * Text content of the post.\r\n */\r\n@Component({\r\n selector: 'post-text',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n display: block;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostTextComponent {}\r\n\r\n/**\r\n * PostMediaComponent\r\n * \r\n * Media container for images/videos.\r\n */\r\n@Component({\r\n selector: 'post-media',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: block;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n ::ng-deep img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n ::ng-deep video {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostMediaComponent {}\r\n\r\n/**\r\n * PostAttachmentsComponent\r\n * \r\n * Container for file attachments, links, etc.\r\n */\r\n@Component({\r\n selector: 'post-attachments',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostAttachmentsComponent {}\r\n\r\n/**\r\n * PostActionsComponent\r\n * \r\n * Action buttons container (like, comment, share).\r\n * \r\n * Contains:\r\n * - `<action-like>` - Like button with count\r\n * - `<action-comment>` - Comment button with count\r\n * - `<action-share>` - Share button\r\n */\r\n@Component({\r\n selector: 'post-actions',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding-top: 4px;\r\n }\r\n \r\n :host:not(.no-indent) {\r\n padding-left: 44px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostActionsComponent {}\r\n\r\n/**\r\n * ActionLikeComponent\r\n * \r\n * Like action button with count display and animated heart icon.\r\n */\r\n@Component({\r\n selector: 'action-like',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.active]': 'active()',\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n #pulseIcon\r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n <ds-icon \r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n </div>\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionLikeComponent {\r\n /**\r\n * Whether the like is active (user has liked)\r\n * Using model() for two-way binding\r\n */\r\n active = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n * Using model() for two-way binding\r\n */\r\n count = model<number>(0);\r\n \r\n /**\r\n * Emits when the like button is clicked\r\n */\r\n likeClick = output<{ active: boolean; count: number }>();\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n async handleClick(event: Event): Promise<void> {\r\n event.stopPropagation();\r\n \r\n // Toggle active state\r\n const newActive = !this.active();\r\n this.active.set(newActive);\r\n \r\n // Update count\r\n const newCount = newActive ? this.count() + 1 : this.count() - 1;\r\n this.count.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newActive) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n // Emit the event with the new state\r\n this.likeClick.emit({ active: newActive, count: newCount });\r\n }\r\n}\r\n\r\n/**\r\n * ActionCommentComponent\r\n * \r\n * Comment action button with count display.\r\n */\r\n@Component({\r\n selector: 'action-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n :host:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <ds-icon name=\"remixChat3Line\" size=\"20px\" />\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionCommentComponent {\r\n /**\r\n * Number of comments\r\n */\r\n count = input<number>(0);\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.commentClick.emit();\r\n }\r\n}\r\n","import { Component, input, output, model, signal, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileCommentComponent\r\n * \r\n * Individual comment component for post discussions.\r\n * Displays user comments with avatar, content, and like action.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-comment\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'1h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [content]=\"'Great post!'\">\r\n * </ds-mobile-comment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent, DsIconButtonComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleCommentClick($event)',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n padding: 8px;\r\n position: relative;\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n background: var(--color-background-primary, #ffffff);\r\n margin-bottom: 8px;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n :host:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n /* Align with comment content: padding (8px) + avatar (32px) + gap (12px) */\r\n left: 44px;\r\n /* Align with comment content right edge: padding (8px) from right */\r\n right: 8px;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:active {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n \r\n .comment-content {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n \r\n .comment-header {\r\n display: flex;\r\n align-items: baseline;\r\n gap: 6px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n /* Wrapper for like and more actions */\r\n .header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin-left: auto;\r\n }\r\n \r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button {\r\n display: none; /* Hidden by default (mobile) */\r\n }\r\n \r\n /* Make button circular */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Show only on desktop with hover capability */\r\n @media (hover: hover) and (pointer: fine) {\r\n .desktop-more-button {\r\n display: block;\r\n }\r\n }\r\n \r\n /* Author styles imported from mobile-common.css */\r\n \r\n .action-like {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 18px;\r\n }\r\n \r\n .like-count {\r\n opacity: 1;\r\n }\r\n \r\n .like-count.hidden {\r\n opacity: 0;\r\n }\r\n \r\n .action-like.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .comment-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n \r\n .comment-text ::ng-deep .mention {\r\n color: var(--color-brand-base, #6B5FF5) !important;\r\n font-weight: 600;\r\n }\r\n \r\n .comment-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n margin-top: 4px;\r\n }\r\n \r\n .action-reply {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .action-reply:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .action-edit {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .action-edit:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n `],\r\n template: `\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n size=\"sm\" />\r\n </div>\r\n \r\n <div class=\"comment-content\">\r\n <div class=\"comment-header\">\r\n <span class=\"author-name\">{{ authorName() }}</span>\r\n <span class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</span>\r\n \r\n <!-- Wrapper for like and more actions -->\r\n <div class=\"header-actions\">\r\n <div \r\n class=\"action-like\"\r\n [class.active]=\"isLiked()\"\r\n (click)=\"toggleLike()\">\r\n <span class=\"like-count\" [class.hidden]=\"likeCount() === 0\">{{ likeCount() }}</span>\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"16px\" />\r\n <ds-icon \r\n [name]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"16px\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Desktop more button -->\r\n <ds-icon-button\r\n class=\"desktop-more-button\"\r\n icon=\"remixMoreFill\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleMoreButtonClick($event)\"\r\n aria-label=\"More options\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"comment-text\" [innerHTML]=\"formattedContent()\"></div>\r\n \r\n <div class=\"comment-actions\">\r\n <div class=\"action-reply\" (click)=\"handleReply()\">\r\n Reply\r\n </div>\r\n @if (isOwnComment()) {\r\n <div class=\"action-edit\" (click)=\"handleEdit()\">\r\n Edit\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileCommentComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"1h ago\", \"2d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Comment content text\r\n */\r\n content = input.required<string>();\r\n \r\n /**\r\n * Avatar initials\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Whether the comment is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Whether this comment belongs to the current user\r\n */\r\n isOwnComment = input<boolean>(false);\r\n \r\n /**\r\n * Whether the comment is liked by current user\r\n */\r\n isLiked = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n */\r\n likeCount = model<number>(0);\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n /**\r\n * Computed property to format content with @mentions\r\n */\r\n formattedContent = computed(() => {\r\n const text = this.content();\r\n // Replace @mentions with styled spans\r\n // Matches @FirstName or @FirstName LastName (max 2 words)\r\n return text.replace(/@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\b/g, '<span class=\"mention\">@$1</span>');\r\n });\r\n \r\n /**\r\n * Emits when the comment card is clicked (if clickable)\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when reply is clicked\r\n */\r\n replyClick = output<void>();\r\n \r\n /**\r\n * Emits when edit is clicked\r\n */\r\n editClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n \r\n handleCommentClick(event: Event): void {\r\n // Only emit if clickable and not clicking on action buttons\r\n if (this.clickable() && !(event.target as HTMLElement).closest('.comment-actions')) {\r\n this.commentClick.emit();\r\n }\r\n }\r\n \r\n async toggleLike(): Promise<void> {\r\n const newLiked = !this.isLiked();\r\n this.isLiked.set(newLiked);\r\n \r\n const newCount = newLiked ? this.likeCount() + 1 : this.likeCount() - 1;\r\n this.likeCount.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newLiked) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }\r\n \r\n handleReply(): void {\r\n this.replyClick.emit();\r\n }\r\n \r\n handleEdit(): void {\r\n this.editClick.emit();\r\n }\r\n \r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n \r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n \r\n // Haptic feedback for long press\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n \r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n \r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n \r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n \r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation and triggers long press action\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n console.log('[Comment] Desktop more button clicked');\r\n event.stopPropagation();\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobilePostComposerComponent\r\n * \r\n * A \"fake\" input composer for creating new posts in the community feed.\r\n * Features a user avatar, placeholder input, and post button.\r\n * Clicking opens the full post creation modal/page.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-post-composer\r\n * [avatarInitials]=\"'LM'\"\r\n * [avatarType]=\"'photo'\"\r\n * [avatarSrc]=\"'...'\"\r\n * (composerClick)=\"openPostCreator()\">\r\n * </ds-mobile-post-composer>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-composer',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent],\r\n host: {\r\n '(click)': 'handleClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n max-width: 640px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n .composer-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .composer-input-wrapper {\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .composer-input {\r\n width: 100%;\r\n background: rgba(255, 255, 255, 0.1);\r\n border: none;\r\n border-radius: 24px;\r\n padding: 10px 16px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: rgba(255, 255, 255, 0.5);\r\n outline: none;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n pointer-events: none;\r\n user-select: none;\r\n }\r\n \r\n .composer-input::placeholder {\r\n color: rgba(255, 255, 255, 0.5);\r\n opacity: 1;\r\n }\r\n \r\n /* Hover effects for desktop */\r\n @media (hover: hover) {\r\n :host:hover .composer-input {\r\n opacity: 0.8;\r\n }\r\n }\r\n `],\r\n template: `\r\n <div class=\"composer-container\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n <div class=\"composer-input-wrapper\">\r\n <input \r\n type=\"text\" \r\n class=\"composer-input\" \r\n [placeholder]=\"placeholder()\"\r\n readonly\r\n tabindex=\"-1\"\r\n />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobilePostComposerComponent {\r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Placeholder text for the input\r\n */\r\n placeholder = input<string>(\"Hvad er nyt?\");\r\n \r\n /**\r\n * Text for the post button\r\n */\r\n buttonText = input<string>('Slå op');\r\n \r\n /**\r\n * Emits when the composer is clicked\r\n */\r\n composerClick = output<void>();\r\n \r\n handleClick(): void {\r\n this.composerClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output, signal, model } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemPostComponent\r\n * \r\n * Specialized interactive list item for displaying social media posts.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays user posts with avatar, content, media, and action buttons.\r\n * Follows Threads-inspired design with clean layout and interactions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-post\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [clickable]=\"true\"\r\n * (postClick)=\"openPost()\">\r\n * \r\n * <post-content>\r\n * <post-text>This is a sample post...</post-text>\r\n * </post-content>\r\n * \r\n * <post-actions>\r\n * <action-like [active]=\"true\" count=\"42\" />\r\n * <action-comment count=\"12\" />\r\n * </post-actions>\r\n * </ds-mobile-interactive-list-item-post>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-post',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsMobileListItemComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .post-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n height: 32px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .author-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .author-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-tertiary, #626B78);\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n bottom: -6px;\r\n right: -6px;\r\n width: 20px;\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-brand-secondary, #5d5fef);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: 2px solid var(--color-background-primary, #ffffff);\r\n }\r\n \r\n .avatar-badge svg {\r\n width: 10px;\r\n position: relative;\r\n top: 1px;\r\n fill: white;\r\n }\r\n \r\n .menu-slot {\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handlePostClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n @if (showBadge()) {\r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"post-header\">\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ authorName() }}</div>\r\n <div class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</div>\r\n </div>\r\n \r\n <div class=\"menu-slot\">\r\n <ng-content select=\"post-menu\" />\r\n </div>\r\n </div>\r\n \r\n <ng-content select=\"post-content\" />\r\n <ng-content select=\"post-actions\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemPostComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2h ago\", \"1d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Show badge on avatar (e.g., for property managers)\r\n */\r\n showBadge = input<boolean>(false);\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related posts\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the post card is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the post card is clicked (if clickable)\r\n */\r\n postClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when the post card is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handlePostClick(): void {\r\n console.log('[InteractiveListItemPost] handlePostClick called, emitting postClick');\r\n this.postClick.emit();\r\n }\r\n \r\n handleCommentClick(): void {\r\n this.commentClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n/**\r\n * PostContentComponent\r\n * \r\n * Main content section of the post.\r\n * \r\n * Contains:\r\n * - `<post-text>` - Text content\r\n * - `<post-media>` - Optional images/videos\r\n * - `<post-attachments>` - Optional file attachments\r\n */\r\n@Component({\r\n selector: 'post-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n margin-bottom: 8px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"post-text\" />\r\n <ng-content select=\"post-media\" />\r\n <ng-content select=\"ds-mobile-inline-photo\" />\r\n <ng-content select=\"post-attachments\" />\r\n `\r\n})\r\nexport class PostContentComponent {}\r\n\r\n/**\r\n * PostTextComponent\r\n * \r\n * Text content of the post.\r\n */\r\n@Component({\r\n selector: 'post-text',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n display: block;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostTextComponent {}\r\n\r\n/**\r\n * PostMediaComponent\r\n * \r\n * Media container for images/videos.\r\n */\r\n@Component({\r\n selector: 'post-media',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: block;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n ::ng-deep img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n ::ng-deep video {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostMediaComponent {}\r\n\r\n/**\r\n * PostAttachmentsComponent\r\n * \r\n * Container for file attachments, links, etc.\r\n */\r\n@Component({\r\n selector: 'post-attachments',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostAttachmentsComponent {}\r\n\r\n/**\r\n * PostActionsComponent\r\n * \r\n * Action buttons container (like, comment, share).\r\n * \r\n * Contains:\r\n * - `<action-like>` - Like button with count\r\n * - `<action-comment>` - Comment button with count\r\n * - `<action-share>` - Share button\r\n */\r\n@Component({\r\n selector: 'post-actions',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding-top: 4px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostActionsComponent {}\r\n\r\n/**\r\n * ActionLikeComponent\r\n * \r\n * Like action button with count display and animated heart icon.\r\n */\r\n@Component({\r\n selector: 'action-like',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.active]': 'active()',\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n #pulseIcon\r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n <ds-icon \r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n </div>\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionLikeComponent {\r\n /**\r\n * Whether the like is active (user has liked)\r\n * Using model() for two-way binding\r\n */\r\n active = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n * Using model() for two-way binding\r\n */\r\n count = model<number>(0);\r\n \r\n /**\r\n * Emits when the like button is clicked\r\n */\r\n likeClick = output<{ active: boolean; count: number }>();\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n async handleClick(event: Event): Promise<void> {\r\n event.stopPropagation();\r\n \r\n // Toggle active state\r\n const newActive = !this.active();\r\n this.active.set(newActive);\r\n \r\n // Update count\r\n const newCount = newActive ? this.count() + 1 : this.count() - 1;\r\n this.count.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newActive) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n // Emit the event with the new state\r\n this.likeClick.emit({ active: newActive, count: newCount });\r\n }\r\n}\r\n\r\n/**\r\n * ActionCommentComponent\r\n * \r\n * Comment action button with count display.\r\n */\r\n@Component({\r\n selector: 'action-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n :host:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <ds-icon name=\"remixChat3Line\" size=\"20px\" />\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionCommentComponent {\r\n /**\r\n * Number of comments\r\n */\r\n count = input<number>(0);\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.commentClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * PostPdfAttachmentComponent\r\n * \r\n * PDF file attachment display for posts.\r\n * Shows PDF info card with icon, filename, and file size.\r\n * Emits click event to open PDF in viewer.\r\n */\r\n@Component({\r\n selector: 'post-pdf-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .pdf-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .pdf-avatar::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .pdf-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .pdf-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .pdf-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"pdf-avatar\">\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"pdf-info\">\r\n <div class=\"pdf-name\">{{ fileName() }}</div>\r\n <div class=\"pdf-meta\">PDF · {{ fileSize() }}</div>\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"24px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class PostPdfAttachmentComponent {\r\n /**\r\n * PDF file name\r\n */\r\n fileName = input<string>('Document.pdf');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * Emits when the PDF attachment is clicked\r\n */\r\n pdfClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.pdfClick.emit();\r\n }\r\n}\r\n\r\n","// Export the main component and shared post components without the indent\r\nexport {\r\n DsMobileInteractiveListItemPostComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from './ds-mobile-interactive-list-item-post';\r\nexport { PostPdfAttachmentComponent } from './ds-mobile-post-pdf-attachment';\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsShapeIndicatorComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemInquiryComponent\r\n * \r\n * Specialized interactive list item for displaying inquiries/tickets.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays inquiry title, description, status, and timestamp.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-inquiry\r\n * [title]=\"'Tumble dryer is not working'\"\r\n * [description]=\"'For the past three days, I have been experiencing...'\"\r\n * [status]=\"'open'\"\r\n * [timestamp]=\"'12 days ago'\"\r\n * [iconName]=\"'remixCalendarLine'\"\r\n * [clickable]=\"true\"\r\n * (inquiryClick)=\"openInquiry()\">\r\n * </ds-mobile-interactive-list-item-inquiry>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-inquiry',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsShapeIndicatorComponent, DsMobileListItemComponent],\r\n styleUrls: ['./ds-mobile-interactive-list-item-inquiry.css'],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .inquiry-icon {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 8px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n \r\n .inquiry-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .inquiry-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .inquiry-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n \r\n .inquiry-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-top: 4px;\r\n }\r\n \r\n .inquiry-status {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-status.open {\r\n color: var(--color-brand-primary, #5d5fef);\r\n }\r\n \r\n .inquiry-status.closed {\r\n color: var(--text-color-default-tertiary, #737373);\r\n }\r\n \r\n .inquiry-timestamp {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handleInquiryClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"inquiry-icon\">\r\n <ds-icon \r\n [name]=\"iconName()\"\r\n size=\"20px\"\r\n [color]=\"iconColor()\" />\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"inquiry-content\">\r\n <h3 class=\"inquiry-title\">{{ title() }}</h3>\r\n \r\n @if (description()) {\r\n <p class=\"inquiry-description\">{{ description() }}</p>\r\n }\r\n \r\n <div class=\"inquiry-meta\">\r\n <div class=\"inquiry-status\" [class.open]=\"status() === 'open'\" [class.closed]=\"status() === 'closed'\">\r\n <ds-shape-indicator \r\n shape=\"circle\" \r\n [variant]=\"status() === 'open' ? 'brand' : 'grey'\">\r\n </ds-shape-indicator>\r\n <span>{{ computedStatusLabel() }}</span>\r\n </div>\r\n \r\n <div class=\"inquiry-timestamp\">\r\n <ds-icon name=\"remixTimeLine\" size=\"14px\" color=\"--color-text-secondary\" />\r\n <span>{{ timestamp() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div content-trailing>\r\n <div class=\"inquiry-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n </div>\r\n }\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemInquiryComponent {\r\n /**\r\n * Inquiry title\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Inquiry description/preview text\r\n */\r\n description = input<string>('');\r\n \r\n /**\r\n * Inquiry status\r\n */\r\n status = input<'open' | 'closed'>('open');\r\n \r\n /**\r\n * Status label (defaults to capitalized status)\r\n */\r\n statusLabel = input<string>('');\r\n \r\n /**\r\n * Timestamp text (e.g., \"12 days ago\", \"2 months ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Icon name for the leading icon\r\n */\r\n iconName = input<string>('remixTodoLine');\r\n \r\n /**\r\n * Icon color\r\n */\r\n iconColor = input<string>('secondary');\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the inquiry item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the inquiry item is clicked (if clickable)\r\n */\r\n inquiryClick = output<void>();\r\n \r\n /**\r\n * Emits when the inquiry item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Get computed status label\r\n */\r\n computedStatusLabel(): string {\r\n if (this.statusLabel()) {\r\n return this.statusLabel();\r\n }\r\n return this.status() === 'open' ? 'Åben' : 'Lukket';\r\n }\r\n \r\n handleInquiryClick(): void {\r\n this.inquiryClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemMessageComponent\r\n * \r\n * Specialized interactive list item for displaying message threads.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays message preview with sender info - simplified version without actions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-message\r\n * [senderName]=\"'John Doe'\"\r\n * [senderRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [message]=\"'Hey, when is the maintenance scheduled?'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [unread]=\"true\"\r\n * [clickable]=\"true\"\r\n * (messageClick)=\"openThread()\">\r\n * </ds-mobile-interactive-list-item-message>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-message',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsMobileListItemComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .message-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n }\r\n \r\n .sender-details {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .sender-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 0;\r\n }\r\n \r\n .sender-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-tertiary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 1;\r\n }\r\n \r\n .unread-indicator {\r\n width: 8px;\r\n height: 8px;\r\n border-radius: 50%;\r\n background: var(--color-brand-primary, #5d5fef);\r\n flex-shrink: 0;\r\n }\r\n \r\n .message-preview {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"'feed'\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handleMessageClick()\"\r\n (longPress)=\"handleLongPress()\">\r\n \r\n <div content-leading>\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n size=\"md\" />\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"message-header\">\r\n <div class=\"sender-details\">\r\n <span class=\"sender-name\">{{ senderName() }}</span>\r\n <span class=\"sender-meta\">{{ senderRole() }}</span>\r\n </div>\r\n \r\n @if (unread()) {\r\n <div class=\"unread-indicator\"></div>\r\n }\r\n </div>\r\n \r\n <p class=\"message-preview\">{{ message() }}</p>\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemMessageComponent {\r\n /**\r\n * Sender's display name\r\n */\r\n senderName = input.required<string>();\r\n \r\n /**\r\n * Sender's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n senderRole = input.required<string>();\r\n \r\n /**\r\n * Message preview text\r\n */\r\n message = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Whether the message is unread\r\n */\r\n unread = input<boolean>(false);\r\n \r\n /**\r\n * Whether the message item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the message item is clicked\r\n */\r\n messageClick = output<void>();\r\n \r\n /**\r\n * Emits when the message item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handleMessageClick(): void {\r\n this.messageClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileContactListItemComponent\r\n * \r\n * Specialized interactive component for displaying contacts.\r\n * Displays contact name with avatar initials and metadata (person name + phone number).\r\n * Similar styling to file attachments with rounded corners and hover states.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-contact-list-item\r\n * [name]=\"'Mortensen & Søn ApS'\"\r\n * [initials]=\"'M'\"\r\n * [contactPerson]=\"'John Mortensen'\"\r\n * [phoneNumber]=\"'+45 12 34 56 78'\"\r\n * [clickable]=\"true\"\r\n * (contactClick)=\"openContact()\">\r\n * </ds-mobile-contact-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-contact-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsAvatarComponent],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleContactClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host.clickable:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .contact-avatar {\r\n flex-shrink: 0;\r\n }\r\n\r\n .contact-content {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .contact-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .contact-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin: 0;\r\n }\r\n \r\n .meta-separator {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n \r\n .contact-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"contact-avatar\">\r\n <ds-avatar\r\n [initials]=\"initials()\"\r\n type=\"initials\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"contact-content\">\r\n <div class=\"contact-name\">{{ name() }}</div>\r\n \r\n @if (contactPerson() || phoneNumber()) {\r\n <div class=\"contact-meta\">\r\n @if (contactPerson()) {\r\n <span>{{ contactPerson() }}</span>\r\n }\r\n @if (contactPerson() && phoneNumber()) {\r\n <span class=\"meta-separator\">·</span>\r\n }\r\n @if (phoneNumber()) {\r\n <span>{{ phoneNumber() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div class=\"contact-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n }\r\n `\r\n})\r\nexport class DsMobileContactListItemComponent {\r\n /**\r\n * Contact/company name\r\n */\r\n name = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (usually 1-2 letters)\r\n */\r\n initials = input.required<string>();\r\n \r\n /**\r\n * Contact person name (optional)\r\n */\r\n contactPerson = input<string>('');\r\n \r\n /**\r\n * Phone number (optional)\r\n */\r\n phoneNumber = input<string>('');\r\n \r\n /**\r\n * Whether the contact item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the contact item is clicked (if clickable)\r\n */\r\n contactClick = output<void>();\r\n \r\n handleContactClick(): void {\r\n if (this.clickable()) {\r\n this.contactClick.emit();\r\n }\r\n }\r\n}\r\n\r\n","import { Component, ElementRef, signal, ViewChild, AfterViewInit, input, output, effect, Injector, computed, inject } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';\r\nimport { \r\n IonTabs, \r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel,\r\n IonHeader, \r\n IonToolbar, \r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent,\r\n Platform\r\n} from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\nexport type HeaderVariant = 'home' | 'simple' | 'back' | 'none';\r\n\r\n/**\r\n * DsMobileAppLayoutComponent\r\n * \r\n * A complete mobile application shell component based on actual mobile page patterns.\r\n * Provides tab navigation, flexible headers, and mobile-optimized layout.\r\n * \r\n * Features:\r\n * - Tab bar navigation with active state\r\n * - Multiple header variants (home with logomark, simple title, back button)\r\n * - Pull-to-refresh support\r\n * - Purple brand background with content wrapper\r\n * - iOS safe area support\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-app-layout\r\n * [showTabBar]=\"true\"\r\n * [tabs]=\"tabsConfig\"\r\n * [headerVariant]=\"'home'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-app-layout',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonTabs,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n IonHeader,\r\n IonToolbar,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-app-layout.css'],\r\n template: `\r\n @if (showTabBar()) {\r\n <!-- Layout with tab bar - NO ion-content, pages provide their own -->\r\n <ion-tabs>\r\n <!-- Tab Bar - dynamic slot based on viewport -->\r\n <ion-tab-bar [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\">\r\n @for (tab of tabs(); track tab.id) {\r\n <ion-tab-button \r\n [tab]=\"tab.id\" \r\n (click)=\"navigateToTab(tab.route)\">\r\n <ds-icon \r\n [name]=\"isTabActive(tab.id) ? tab.iconActive : tab.icon\" \r\n size=\"24px\" \r\n />\r\n <ion-label>{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n }\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n } @else {\r\n <!-- Standalone layout (no tabs) -->\r\n @if (headerVariant() !== 'none') {\r\n <ion-header>\r\n <ion-toolbar>\r\n @switch (headerVariant()) {\r\n @case ('home') {\r\n <div class=\"header-home\">\r\n <svg class=\"logomark\" width=\"36\" height=\"32\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n <div class=\"header-home__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n (click)=\"handleAvatarClick()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n @case ('back') {\r\n <div class=\"header-back\">\r\n @if (showBackButton()) {\r\n <button class=\"back-button\" (click)=\"handleBackClick()\">\r\n <ds-icon name=\"remixArrowLeftSLine\" size=\"24px\" />\r\n </button>\r\n }\r\n <h1 class=\"header-title\">{{ pageTitle() }}</h1>\r\n </div>\r\n }\r\n @case ('simple') {\r\n <div class=\"header-simple\">\r\n <h1 class=\"header-title\">{{ pageTitle() }}</h1>\r\n </div>\r\n }\r\n }\r\n </ion-toolbar>\r\n </ion-header>\r\n }\r\n\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n @if (showPullToRefresh() && isNativePlatform()) {\r\n <ion-refresher\r\n slot=\"fixed\"\r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\"\r\n [pullMin]=\"80\"\r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"remixArrowDownS\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <ng-content></ng-content>\r\n </ion-content>\r\n }\r\n `\r\n})\r\nexport class DsMobileAppLayoutComponent implements AfterViewInit {\r\n @ViewChild(IonContent, { static: false }) ionContent!: IonContent;\r\n\r\n // Platform detection\r\n private platform = inject(Platform);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n\r\n // Inputs\r\n headerVariant = input<HeaderVariant>('simple');\r\n pageTitle = input<string>('');\r\n showBackButton = input<boolean>(false);\r\n showPullToRefresh = input<boolean>(false);\r\n showTabBar = input<boolean>(false);\r\n tabs = input<TabConfig[]>([]);\r\n \r\n // Avatar inputs (for home header)\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n avatarInitials = input<string>('U');\r\n avatarSrc = input<string>('');\r\n avatarIconName = input<string>('remixUser3Line');\r\n\r\n // Outputs\r\n backClick = output<void>();\r\n refresh = output<any>();\r\n avatarClick = output<void>();\r\n scroll = output<any>();\r\n\r\n // Internal state\r\n private scrollY = signal(0);\r\n activeTab = signal<string>('home');\r\n isDesktop = signal<boolean>(false);\r\n\r\n constructor(\r\n private router: Router,\r\n private elementRef: ElementRef,\r\n private breakpointObserver: BreakpointObserver\r\n ) {\r\n // Track active tab based on current route\r\n this.router.events.subscribe(() => {\r\n const url = this.router.url;\r\n const tab = this.tabs().find(t => url.includes(t.route));\r\n if (tab) {\r\n this.activeTab.set(tab.id);\r\n }\r\n });\r\n \r\n // Track breakpoint for tab bar positioning\r\n this.breakpointObserver.observe(['(min-width: 768px)'])\r\n .subscribe(result => {\r\n this.isDesktop.set(result.matches);\r\n });\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n if (this.ionContent) {\r\n this.ionContent.scrollEvents = true;\r\n this.ensureScrollable();\r\n }\r\n }\r\n\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop || 0;\r\n this.scrollY.set(scrollTop);\r\n this.scroll.emit(event);\r\n }\r\n\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n this.refresh.emit(event);\r\n // Note: Parent component should handle event.target.complete()\r\n // If no handler is provided, you can add a default timeout in the parent\r\n }\r\n\r\n handleBackClick(): void {\r\n this.backClick.emit();\r\n }\r\n\r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n\r\n navigateToTab(route: string): void {\r\n this.router.navigateByUrl(route, { replaceUrl: true });\r\n }\r\n\r\n private ensureScrollable(): void {\r\n if (this.ionContent) {\r\n this.ionContent.getScrollElement().then((scrollEl: HTMLElement) => {\r\n if (scrollEl) {\r\n scrollEl.style.overscrollBehaviorY = 'none';\r\n (scrollEl.style as any).webkitOverflowScrolling = 'touch';\r\n }\r\n });\r\n }\r\n }\r\n\r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n}\r\n\r\n","import { Component, Input, Output, EventEmitter, signal, OnInit, AfterViewInit, ElementRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RouterLink, RouterLinkActive } from '@angular/router';\r\nimport { \r\n IonTabs, \r\n IonTab,\r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\n/**\r\n * DsMobileTabsComponent\r\n * \r\n * Responsive tab navigation that adapts from mobile to desktop:\r\n * - Mobile (< 768px): Bottom tab bar with icons + labels\r\n * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar\r\n * \r\n * Wraps ion-tabs to maintain native routing functionality while\r\n * providing a responsive navigation experience with branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tabs\r\n * [tabs]=\"tabsConfig\"\r\n * [avatarInitials]=\"'JD'\"\r\n * (avatarClick)=\"handleAvatarClick()\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tabs',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n RouterLink,\r\n RouterLinkActive,\r\n IonTabs,\r\n IonTab,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-tabs.css'],\r\n template: `\r\n <ion-tabs>\r\n <ng-container *ngIf=\"tabs && tabs.length > 0\">\r\n <ion-tab *ngFor=\"let tab of tabs; trackBy: trackByTabId\" [tab]=\"tab.id\"></ion-tab>\r\n </ng-container>\r\n \r\n <ion-tab-bar \r\n [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\" \r\n class=\"ds-tab-bar\"\r\n [class.ds-tab-bar--desktop]=\"isDesktop()\">\r\n \r\n <!-- Logo (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__logo\">\r\n <svg class=\"logomark\" width=\"32\" height=\"28\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n \r\n <!-- Tab buttons container -->\r\n <div class=\"ds-tab-bar__tabs\" *ngIf=\"tabs\">\r\n <ion-tab-button \r\n *ngFor=\"let tab of tabs; trackBy: trackByTabId\"\r\n [tab]=\"tab.id\"\r\n [routerLink]=\"['/', tab.route]\"\r\n routerLinkActive=\"tab-selected\"\r\n [routerLinkActiveOptions]=\"{ exact: false }\"\r\n [attr.data-icon]=\"tab.icon\"\r\n [attr.data-icon-active]=\"tab.iconActive\"\r\n [attr.aria-label]=\"tab.label\"\r\n class=\"ds-tab-button ion-activatable\"\r\n [class.tab-selected]=\"isTabActive(tab.id)\">\r\n <div class=\"tab-icon-ripple\"></div>\r\n <div class=\"tab-icon-wrapper\">\r\n <ds-icon \r\n [name]=\"tab.icon\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-inactive\"\r\n />\r\n <ds-icon \r\n [name]=\"tab.iconActive\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-active\"\r\n />\r\n </div>\r\n <ion-label [attr.aria-hidden]=\"true\">{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n </div>\r\n \r\n <!-- Avatar (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType\"\r\n [initials]=\"avatarInitials\"\r\n [src]=\"avatarSrc\"\r\n [iconName]=\"avatarIconName\"\r\n (click)=\"handleAvatarClick()\"\r\n />\r\n </div>\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n `\r\n})\r\nexport class DsMobileTabsComponent implements OnInit, AfterViewInit {\r\n // Inputs\r\n @Input() tabs: TabConfig[] = [];\r\n \r\n // Avatar inputs\r\n @Input() avatarType: 'initials' | 'photo' | 'icon' = 'initials';\r\n @Input() avatarInitials: string = 'U';\r\n @Input() avatarSrc: string = '';\r\n @Input() avatarIconName: string = 'remixUser3Line';\r\n \r\n // Outputs\r\n @Output() avatarClick = new EventEmitter<void>();\r\n \r\n // Internal state\r\n activeTab = signal<string>('');\r\n isDesktop = signal<boolean>(false);\r\n \r\n private mutationObserver?: MutationObserver;\r\n \r\n constructor(private elementRef: ElementRef) {}\r\n \r\n ngOnInit(): void {\r\n console.log('DsMobileTabsComponent initialized');\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial removal\r\n this.removeTitleAttributes();\r\n \r\n // Set up mutation observer to continuously remove title attributes\r\n this.setupTitleRemovalObserver();\r\n }\r\n \r\n ngOnDestroy(): void {\r\n if (this.mutationObserver) {\r\n this.mutationObserver.disconnect();\r\n }\r\n }\r\n \r\n private setupTitleRemovalObserver(): void {\r\n const config = { \r\n attributes: true, \r\n attributeFilter: ['title'],\r\n subtree: true,\r\n childList: true\r\n };\r\n \r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'attributes' && mutation.attributeName === 'title') {\r\n const target = mutation.target as HTMLElement;\r\n if (target.tagName === 'ION-TAB-BUTTON' && target.hasAttribute('title')) {\r\n target.removeAttribute('title');\r\n }\r\n }\r\n });\r\n // Also do a sweep after any changes\r\n this.removeTitleAttributes();\r\n });\r\n \r\n this.mutationObserver.observe(this.elementRef.nativeElement, config);\r\n }\r\n \r\n private removeTitleAttributes(): void {\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n tabButtons.forEach((button: HTMLElement) => {\r\n if (button.hasAttribute('title')) {\r\n button.removeAttribute('title');\r\n }\r\n // Also remove from the native button inside shadow DOM\r\n const nativeButton = button.shadowRoot?.querySelector('button');\r\n if (nativeButton?.hasAttribute('title')) {\r\n nativeButton.removeAttribute('title');\r\n }\r\n });\r\n }\r\n \r\n trackByTabId(index: number, tab: TabConfig): string {\r\n return tab.id;\r\n }\r\n \r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n \r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport type { LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxHeaderComponent\r\n * \r\n * Shared header component for all lightbox types (image, PDF, etc.)\r\n * Displays author information and close button with consistent styling.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-header',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent, DsAvatarComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n template: `\r\n @if (author()) {\r\n <div class=\"lightbox-header lightbox-context\">\r\n <div class=\"header-content\">\r\n <!-- Post author info -->\r\n <div class=\"post-author-info\">\r\n <ds-avatar\r\n [initials]=\"author()!.avatarInitials ?? ''\"\r\n [type]=\"author()!.avatarType ?? 'initials'\"\r\n [src]=\"author()!.avatarSrc ?? ''\"\r\n size=\"md\"\r\n />\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ author()!.name }}</div>\r\n <div class=\"author-meta\">\r\n @if (author()!.role) {\r\n <span>{{ author()!.role }}</span>\r\n }\r\n @if (author()!.role && author()!.timestamp) {\r\n <span class=\"separator\">·</span>\r\n }\r\n @if (author()!.timestamp) {\r\n <span>{{ author()!.timestamp }}</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"closeClick.emit()\"\r\n class=\"close-button\"\r\n [ariaLabel]=\"'Close'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n }\r\n `,\r\n styles: [`\r\n .lightbox-header {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 1000;\r\n padding: 0 16px;\r\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.4) 80%, transparent 100%);\r\n pointer-events: none;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n pointer-events: auto;\r\n }\r\n\r\n .post-author-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n .author-name {\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n }\r\n\r\n .author-meta {\r\n color: rgba(255, 255, 255, 0.7);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n\r\n .author-meta .separator {\r\n color: rgba(255, 255, 255, 0.5);\r\n }\r\n\r\n .close-button {\r\n pointer-events: auto;\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .close-button::ng-deep button {\r\n color: white !important;\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border-radius: 50%;\r\n transition: background 0.2s ease;\r\n border: none;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .close-button::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep button:active {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep svg {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Safe area support for notched devices */\r\n @supports (padding-top: env(safe-area-inset-top)) {\r\n .lightbox-header {\r\n padding-top: calc(16px + env(safe-area-inset-top));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxHeaderComponent {\r\n /**\r\n * Author information to display\r\n */\r\n author = input<LightboxAuthor>();\r\n\r\n /**\r\n * Emitted when close button is clicked\r\n */\r\n closeClick = output<void>();\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileLightboxFooterComponent\r\n * \r\n * Shared footer component for all lightbox types (image, PDF, etc.)\r\n * Displays navigation controls (for multiple images) and action buttons.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-footer',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n template: `\r\n <div class=\"lightbox-footer\">\r\n <!-- Navigation controls (only shown for multiple images) -->\r\n @if (showNavigation() && totalImages() > 1) {\r\n <div class=\"footer-navigation\">\r\n <button \r\n class=\"nav-button prev\"\r\n (click)=\"prevClick.emit()\"\r\n [disabled]=\"currentIndex() === 0\"\r\n aria-label=\"Previous image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n \r\n <div class=\"counter\">\r\n {{ currentIndex() + 1 }} / {{ totalImages() }}\r\n </div>\r\n \r\n <button \r\n class=\"nav-button next\"\r\n (click)=\"nextClick.emit()\"\r\n [disabled]=\"currentIndex() === totalImages() - 1\"\r\n aria-label=\"Next image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n \r\n <!-- Action buttons -->\r\n <div class=\"footer-actions\">\r\n <div class=\"action-buttons-left\">\r\n <!-- Like button -->\r\n <ds-icon-button\r\n [icon]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"likeClick.emit()\"\r\n [attr.data-liked]=\"isLiked()\"\r\n class=\"action-button-like\"\r\n [ariaLabel]=\"'Like'\">\r\n </ds-icon-button>\r\n \r\n <!-- Comment button -->\r\n <ds-icon-button\r\n icon=\"remixChat3Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"commentClick.emit()\"\r\n class=\"action-button-comment\"\r\n [ariaLabel]=\"'Comment'\">\r\n </ds-icon-button>\r\n </div>\r\n \r\n <ds-icon-button\r\n icon=\"remixShare2Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"shareClick.emit()\"\r\n class=\"action-button-share\"\r\n [ariaLabel]=\"'Share'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n .lightbox-footer {\r\n position: fixed;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 100;\r\n padding: 16px 20px 20px 20px;\r\n background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.6) 50%, rgba(0, 0, 0, 0.4) 75%, transparent 100%);\r\n pointer-events: none;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n\r\n /* Navigation controls */\r\n .footer-navigation {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 24px;\r\n pointer-events: auto;\r\n }\r\n\r\n .nav-button {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n border-radius: 50%;\r\n color: white;\r\n width: 40px;\r\n height: 40px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n padding: 0;\r\n }\r\n\r\n .nav-button:hover:not(:disabled) {\r\n background: rgba(255, 255, 255, 0.2);\r\n transform: scale(1.05);\r\n }\r\n\r\n .nav-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .nav-button:disabled {\r\n opacity: 0.3;\r\n cursor: not-allowed;\r\n }\r\n\r\n .nav-button svg {\r\n width: 24px;\r\n height: 24px;\r\n flex-shrink: 0;\r\n }\r\n\r\n .counter {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: 100px;\r\n padding: 8px 16px;\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 1;\r\n letter-spacing: -0.3px;\r\n pointer-events: auto;\r\n user-select: none;\r\n }\r\n\r\n .footer-actions {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 16px;\r\n pointer-events: auto;\r\n }\r\n\r\n .action-buttons-left {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n\r\n /* Style the action buttons to match the ghost/transparent look */\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button,\r\n .action-button-share::ng-deep button {\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border: 1px solid rgba(255, 255, 255, 0.2) !important;\r\n color: white !important;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n transition: all 0.2s ease;\r\n }\r\n\r\n .action-button-like::ng-deep button:hover,\r\n .action-button-comment::ng-deep button:hover,\r\n .action-button-share::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.2) !important;\r\n transform: scale(1.02);\r\n }\r\n\r\n .action-button-like::ng-deep button:active,\r\n .action-button-comment::ng-deep button:active,\r\n .action-button-share::ng-deep button:active {\r\n transform: scale(0.98);\r\n }\r\n\r\n /* Icon and label colors */\r\n .action-button-like::ng-deep button svg,\r\n .action-button-comment::ng-deep button svg,\r\n .action-button-share::ng-deep button svg,\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon,\r\n .action-button-share::ng-deep button .btn__icon,\r\n .action-button-like::ng-deep button .btn__content,\r\n .action-button-comment::ng-deep button .btn__content {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Make sure icons are visible */\r\n .action-button-like::ng-deep button .btn__icon svg,\r\n .action-button-comment::ng-deep button .btn__icon svg,\r\n .action-button-share::ng-deep button .btn__icon svg {\r\n color: white !important;\r\n fill: white !important;\r\n display: block !important;\r\n opacity: 1 !important;\r\n visibility: visible !important;\r\n width: 20px !important;\r\n height: 20px !important;\r\n }\r\n\r\n /* Ensure icon wrapper is visible */\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon,\r\n .action-button-share::ng-deep button .btn__icon {\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n flex-shrink: 0 !important;\r\n }\r\n\r\n /* Like button active state (pink heart) */\r\n .action-button-like[data-liked=\"true\"]::ng-deep button svg {\r\n fill: #f91880 !important;\r\n color: #f91880 !important;\r\n }\r\n\r\n .action-button-like[data-liked=\"true\"]::ng-deep button {\r\n border-color: rgba(249, 24, 128, 0.3) !important;\r\n }\r\n\r\n /* All action buttons should have same circular styling */\r\n .action-button-like,\r\n .action-button-comment,\r\n .action-button-share {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button,\r\n .action-button-share::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 44px !important;\r\n height: 44px !important;\r\n min-width: 44px !important;\r\n min-height: 44px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n /* Safe area support for footer */\r\n @supports (padding-bottom: env(safe-area-inset-bottom)) {\r\n .lightbox-footer {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxFooterComponent {\r\n /**\r\n * Whether to show navigation controls\r\n */\r\n showNavigation = input<boolean>(false);\r\n\r\n /**\r\n * Current image index (0-based)\r\n */\r\n currentIndex = input<number>(0);\r\n\r\n /**\r\n * Total number of images\r\n */\r\n totalImages = input<number>(1);\r\n\r\n /**\r\n * Whether the content is liked\r\n */\r\n isLiked = input<boolean>(false);\r\n\r\n /**\r\n * Number of likes\r\n */\r\n likeCount = input<number>(0);\r\n\r\n /**\r\n * Number of comments\r\n */\r\n commentCount = input<number>(0);\r\n\r\n /**\r\n * Emitted when previous button is clicked\r\n */\r\n prevClick = output<void>();\r\n\r\n /**\r\n * Emitted when next button is clicked\r\n */\r\n nextClick = output<void>();\r\n\r\n /**\r\n * Emitted when like button is clicked\r\n */\r\n likeClick = output<void>();\r\n\r\n /**\r\n * Emitted when comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n\r\n /**\r\n * Emitted when share button is clicked\r\n */\r\n shareClick = output<void>();\r\n}\r\n\r\n","import {\r\n Component,\r\n signal,\r\n computed,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n HostListener\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonSpinner,\r\n GestureController,\r\n Gesture\r\n} from '@ionic/angular/standalone';\r\nimport { Share } from '@capacitor/share';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxImage, LightboxAuthor } from './ds-mobile-lightbox.service';\r\nimport Swiper from 'swiper';\r\nimport type { SwiperOptions } from 'swiper/types';\r\n\r\n/**\r\n * DsMobileLightboxImageComponent\r\n * \r\n * Full-screen image lightbox component with Swiper.js navigation and pinch-zoom.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - Swiper.js for smooth image navigation\r\n * - Pinch to zoom in/out\r\n * - Double-tap to toggle zoom\r\n * - Swipe down to close (when not zoomed)\r\n * - Image counter and navigation controls\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openImage() {\r\n * this.lightbox.openImages({\r\n * images: [{ type: 'image', src: 'image.jpg', title: 'My Image' }]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-image',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonSpinner,\r\n DsIconButtonComponent,\r\n DsAvatarComponent,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"lightbox-overlay\" \r\n [class.zoomed]=\"isZoomed()\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and close button -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n />\r\n\r\n <!-- Swiper container -->\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n @for (image of images; track image.src; let i = $index) {\r\n <div class=\"swiper-slide\">\r\n <div class=\"image-zoom-container\" [attr.data-index]=\"i\">\r\n <img \r\n [src]=\"image.src\"\r\n [alt]=\"image.alt || 'Lightbox image'\"\r\n class=\"lightbox-image\"\r\n (load)=\"onImageLoad(i)\"\r\n (error)=\"onImageError(i)\">\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <!-- Loading indicator -->\r\n @if (isLoading()) {\r\n <div class=\"loading-spinner\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n </div>\r\n }\r\n\r\n <!-- Footer with navigation and actions -->\r\n <ds-mobile-lightbox-footer\r\n [showNavigation]=\"showControls && images.length > 1\"\r\n [currentIndex]=\"currentIndex()\"\r\n [totalImages]=\"images.length\"\r\n [isLiked]=\"isLiked()\"\r\n [likeCount]=\"likeCount()\"\r\n [commentCount]=\"commentCount()\"\r\n (prevClick)=\"previousImage()\"\r\n (nextClick)=\"nextImage()\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n </div>\r\n </div>\r\n `,\r\n styleUrl: './ds-mobile-lightbox.css'\r\n})\r\nexport class DsMobileLightboxImageComponent implements OnInit, AfterViewInit, OnDestroy {\r\n // Inputs (passed from service as regular properties, not signals)\r\n images!: LightboxImage[];\r\n author?: LightboxAuthor;\r\n initialIndex: number = 0;\r\n enableZoom: boolean = true;\r\n showControls: boolean = true;\r\n enableSwipe: boolean = true;\r\n showInfo: boolean = true;\r\n animation: 'fade' | 'zoom' | 'slide' = 'fade';\r\n onCloseRequested?: () => void;\r\n\r\n // View children\r\n @ViewChild('swiperContainer', { read: ElementRef }) swiperContainer!: ElementRef<HTMLDivElement>;\r\n\r\n // State\r\n currentIndex = signal(0);\r\n scale = signal(1);\r\n isZoomed = signal(false);\r\n isLoading = signal(true);\r\n hasError = signal(false);\r\n \r\n // Action states\r\n isLiked = signal(false);\r\n likeCount = signal(0);\r\n commentCount = signal(0);\r\n\r\n // Computed\r\n currentImage = computed(() => this.images[this.currentIndex()]);\r\n\r\n // Swiper instance\r\n private swiper?: Swiper;\r\n private zoomData: Map<number, { scale: number; x: number; y: number }> = new Map();\r\n\r\n constructor(\r\n private gestureCtrl: GestureController\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Set initial index from the passed property\r\n if (this.initialIndex !== undefined) {\r\n this.currentIndex.set(this.initialIndex);\r\n }\r\n \r\n // Initialize action states from current image\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n this.initializeZoomGestures();\r\n }, 100);\r\n }\r\n\r\n ngOnDestroy(): void {\r\n // Clean up Swiper\r\n if (this.swiper) {\r\n this.swiper.destroy();\r\n this.swiper = undefined;\r\n }\r\n }\r\n /**\r\n * Initialize Swiper for image navigation\r\n */\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) {\r\n console.error('[Lightbox] Swiper container not found');\r\n return;\r\n }\r\n\r\n const swiperOptions: SwiperOptions = {\r\n initialSlide: this.initialIndex,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n slidesPerView: 1,\r\n spaceBetween: 0,\r\n touchRatio: 1,\r\n longSwipesRatio: 0.5,\r\n threshold: 10,\r\n on: {\r\n slideChange: (swiper) => {\r\n this.currentIndex.set(swiper.activeIndex);\r\n this.updateActionStates();\r\n \r\n // Check if the image is already loaded\r\n const currentSlide = swiper.slides[swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n // Image is already loaded\r\n this.isLoading.set(false);\r\n }\r\n },\r\n slideChangeTransitionStart: () => {\r\n // Don't show loading spinner if image is already loaded\r\n const currentSlide = this.swiper?.slides[this.swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (!img || !img.complete || img.naturalHeight === 0) {\r\n this.isLoading.set(true);\r\n }\r\n }\r\n }\r\n };\r\n\r\n this.swiper = new Swiper(this.swiperContainer.nativeElement, swiperOptions);\r\n \r\n // Check if the initial image is already loaded\r\n setTimeout(() => {\r\n const currentSlide = this.swiper?.slides[this.currentIndex()];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n this.isLoading.set(false);\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * Initialize pinch-zoom gestures for all slides\r\n */\r\n private initializeZoomGestures(): void {\r\n if (!this.enableZoom) return;\r\n\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.image-zoom-container');\r\n \r\n slides.forEach((slide, index) => {\r\n this.initializeZoomForSlide(slide as HTMLElement, index);\r\n });\r\n }\r\n\r\n /**\r\n * Initialize zoom gestures for a specific slide\r\n */\r\n private initializeZoomForSlide(container: HTMLElement, index: number): void {\r\n let initialDistance = 0;\r\n let initialScale = 1;\r\n let currentScale = 1;\r\n let lastTap = 0;\r\n\r\n // Double-tap to zoom\r\n container.addEventListener('click', (event: MouseEvent) => {\r\n const now = Date.now();\r\n const timeSinceLastTap = now - lastTap;\r\n\r\n if (timeSinceLastTap < 300 && timeSinceLastTap > 0) {\r\n event.preventDefault();\r\n this.toggleZoom(container, index);\r\n }\r\n\r\n lastTap = now;\r\n });\r\n\r\n // Pinch to zoom\r\n const getTouchDistance = (touches: TouchList) => {\r\n const dx = touches[0].clientX - touches[1].clientX;\r\n const dy = touches[0].clientY - touches[1].clientY;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n };\r\n\r\n container.addEventListener('touchstart', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n initialDistance = getTouchDistance(event.touches);\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n initialScale = zoomData.scale;\r\n \r\n // Disable Swiper when zooming\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchmove', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n \r\n const currentDistance = getTouchDistance(event.touches);\r\n const pinchScale = currentDistance / initialDistance;\r\n \r\n currentScale = Math.max(1, Math.min(initialScale * pinchScale, 4));\r\n \r\n const img = container.querySelector('img');\r\n if (img) {\r\n img.style.transform = `scale(${currentScale})`;\r\n }\r\n \r\n if (currentScale > 1) {\r\n this.isZoomed.set(true);\r\n } else {\r\n this.isZoomed.set(false);\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchend', (event: TouchEvent) => {\r\n if (event.touches.length < 2) {\r\n // Save zoom state\r\n this.zoomData.set(index, { scale: currentScale, x: 0, y: 0 });\r\n \r\n // Re-enable Swiper if not zoomed\r\n if (this.swiper && currentScale <= 1) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Toggle zoom on double-tap\r\n */\r\n private toggleZoom(container: HTMLElement, index: number): void {\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n const img = container.querySelector('img');\r\n \r\n if (!img) return;\r\n\r\n if (zoomData.scale > 1) {\r\n // Zoom out\r\n img.style.transform = 'scale(1)';\r\n this.zoomData.set(index, { scale: 1, x: 0, y: 0 });\r\n this.isZoomed.set(false);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n } else {\r\n // Zoom in\r\n img.style.transform = 'scale(2)';\r\n this.zoomData.set(index, { scale: 2, x: 0, y: 0 });\r\n this.isZoomed.set(true);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Update action states (like, comments) when slide changes\r\n */\r\n private updateActionStates(): void {\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n /**\r\n * Close the lightbox\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle share button click\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[Lightbox] Share button clicked');\r\n const currentImg = this.currentImage();\r\n \r\n try {\r\n await Share.share({\r\n title: currentImg.title || 'Shared Image',\r\n url: currentImg.src,\r\n dialogTitle: 'Share Image',\r\n });\r\n } catch (error) {\r\n console.error('[Lightbox] Share failed:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Handle like button toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[Lightbox] Like button toggled');\r\n this.isLiked.update(liked => !liked);\r\n \r\n if (this.isLiked()) {\r\n this.likeCount.update(count => count + 1);\r\n } else {\r\n this.likeCount.update(count => Math.max(0, count - 1));\r\n }\r\n }\r\n\r\n /**\r\n * Handle reply/comment button click\r\n */\r\n onReply(): void {\r\n console.log('[Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the next image\r\n */\r\n nextImage(): void {\r\n if (this.swiper && this.currentIndex() < this.images.length - 1) {\r\n this.swiper.slideNext();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the previous image\r\n */\r\n previousImage(): void {\r\n if (this.swiper && this.currentIndex() > 0) {\r\n this.swiper.slidePrev();\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load success\r\n */\r\n onImageLoad(index: number): void {\r\n if (index === this.currentIndex()) {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load error\r\n */\r\n onImageError(index: number): void {\r\n if (index === this.currentIndex()) {\r\n console.error(`[Lightbox] Image ${index} failed to load`);\r\n this.isLoading.set(false);\r\n this.hasError.set(true);\r\n }\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonContent,\r\n IonSpinner\r\n} from '@ionic/angular/standalone';\r\nimport { Filesystem, Directory } from '@capacitor/filesystem';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Share } from '@capacitor/share';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxPdf, LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxPdfComponent\r\n * \r\n * PDF viewer component that displays PDF info and allows users to open PDFs in the native device viewer.\r\n * Shows a lightbox with PDF details first, then user can choose to open in native viewer.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - PDF info preview (title, size, icon)\r\n * - User-initiated native PDF viewing (iOS/Android)\r\n * - Download and cache support\r\n * - Share functionality\r\n * - Loading states\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openPdf() {\r\n * this.lightbox.openPdf({\r\n * pdf: { type: 'pdf', src: 'document.pdf', title: 'My Document' }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-pdf',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonContent,\r\n IonSpinner,\r\n DsAvatarComponent,\r\n DsButtonComponent,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content \r\n [fullscreen]=\"true\"\r\n class=\"lightbox-content pdf-viewer\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and close button -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n />\r\n\r\n <!-- PDF Info & Actions -->\r\n <div class=\"pdf-container\">\r\n @if (isLoading) {\r\n <div class=\"loading-state\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n <p>Loading PDF...</p>\r\n </div>\r\n } @else if (hasError) {\r\n <div class=\"error-state\">\r\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M12 8V12M12 16H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n <h3>Failed to Load PDF</h3>\r\n <p>{{ errorMessage }}</p>\r\n <button class=\"retry-button\" (click)=\"openPdfInNativeViewer()\">\r\n Try Again\r\n </button>\r\n </div>\r\n } @else {\r\n <div class=\"pdf-content\">\r\n <!-- PDF Icon -->\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"xl\"\r\n />\r\n \r\n <!-- PDF Title (same as attachment fileName) -->\r\n <h2 class=\"pdf-title\">{{ getDisplayTitle() }}</h2>\r\n \r\n <!-- PDF Metadata (same format as attachment: PDF · fileSize) -->\r\n <div class=\"pdf-meta\">\r\n PDF · {{ pdf.fileSize ? formatFileSize(pdf.fileSize) : '' }}\r\n </div>\r\n \r\n <!-- Open Button -->\r\n <ds-button\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (clicked)=\"openPdfInNativeViewer()\"\r\n class=\"open-pdf-button\">\r\n Open Preview\r\n </ds-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Bottom actions -->\r\n <ds-mobile-lightbox-footer\r\n [isLiked]=\"false\"\r\n [likeCount]=\"0\"\r\n [commentCount]=\"0\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n </div>\r\n </ion-content>\r\n `,\r\n styleUrl: './ds-mobile-lightbox-pdf.css'\r\n})\r\nexport class DsMobileLightboxPdfComponent implements OnInit {\r\n // Inputs (passed from service as regular properties)\r\n pdf!: LightboxPdf;\r\n author?: LightboxAuthor;\r\n onCloseRequested?: () => void;\r\n\r\n // State\r\n isLoading = false;\r\n hasError = false;\r\n errorMessage = '';\r\n cachedFilePath?: string;\r\n\r\n constructor() {}\r\n\r\n ngOnInit(): void {\r\n console.log('[PDF Lightbox] Initializing with PDF:', this.pdf);\r\n \r\n // Don't automatically open - let user click the \"Open\" button\r\n // this.openPdfInNativeViewer();\r\n }\r\n\r\n /**\r\n * Open the PDF in the native device viewer\r\n */\r\n async openPdfInNativeViewer(): Promise<void> {\r\n if (!this.pdf?.src) {\r\n console.error('[PDF Lightbox] No PDF source provided');\r\n this.hasError = true;\r\n this.errorMessage = 'No PDF file provided';\r\n return;\r\n }\r\n\r\n this.isLoading = true;\r\n this.hasError = false;\r\n this.errorMessage = '';\r\n\r\n try {\r\n console.log('[PDF Lightbox] Opening PDF:', this.pdf.src);\r\n \r\n // Check if it's already a full URL\r\n let pdfUrl: string;\r\n \r\n if (this.pdf.src.startsWith('http://') || this.pdf.src.startsWith('https://')) {\r\n // Already a full URL\r\n pdfUrl = this.pdf.src;\r\n } else {\r\n // Relative path - construct full URL\r\n // Use current origin (which includes the dev server URL in Capacitor)\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n pdfUrl = `${window.location.origin}/${cleanPath}`;\r\n }\r\n \r\n console.log('[PDF Lightbox] Opening PDF at URL:', pdfUrl);\r\n \r\n // Use Browser to open the PDF\r\n await Browser.open({ \r\n url: pdfUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n this.isLoading = false;\r\n \r\n // Close the modal after opening browser\r\n setTimeout(() => {\r\n this.close();\r\n }, 500);\r\n } catch (error: any) {\r\n console.error('[PDF Lightbox] Error opening PDF:', error);\r\n this.isLoading = false;\r\n this.hasError = true;\r\n this.errorMessage = error?.message || 'Failed to open PDF';\r\n }\r\n }\r\n\r\n /**\r\n * Download a remote PDF and open it\r\n */\r\n private async downloadAndOpenPdf(): Promise<void> {\r\n try {\r\n console.log('[PDF Lightbox] Downloading PDF from:', this.pdf.src);\r\n \r\n // Fetch the PDF\r\n const response = await fetch(this.pdf.src);\r\n if (!response.ok) {\r\n throw new Error(`Failed to download PDF: ${response.statusText}`);\r\n }\r\n \r\n const blob = await response.blob();\r\n const base64Data = await this.blobToBase64(blob);\r\n \r\n // Generate a filename\r\n const fileName = this.pdf.title \r\n ? `${this.pdf.title.replace(/[^a-z0-9]/gi, '_')}.pdf`\r\n : 'document.pdf';\r\n \r\n // Save to cache directory\r\n const result = await Filesystem.writeFile({\r\n path: fileName,\r\n data: base64Data,\r\n directory: Directory.Cache\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF saved to cache:', result.uri);\r\n this.cachedFilePath = result.uri;\r\n \r\n // Open using Browser\r\n await Browser.open({ \r\n url: result.uri,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error downloading/opening PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Open a local PDF file\r\n */\r\n private async openLocalPdf(): Promise<void> {\r\n try {\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n const fullUrl = window.location.origin + '/' + cleanPath;\r\n \r\n await Browser.open({ \r\n url: fullUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] Local PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error opening local PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Convert Blob to base64 string\r\n */\r\n private blobToBase64(blob: Blob): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onloadend = () => {\r\n const base64String = reader.result as string;\r\n // Remove the data URL prefix\r\n const base64Data = base64String.split(',')[1];\r\n resolve(base64Data);\r\n };\r\n reader.onerror = reject;\r\n reader.readAsDataURL(blob);\r\n });\r\n }\r\n\r\n /**\r\n * Get display title with file extension\r\n * If title is provided, ensure it has .pdf extension\r\n * Otherwise, extract filename from src\r\n */\r\n getDisplayTitle(): string {\r\n if (this.pdf.title) {\r\n // If title doesn't end with .pdf, add it\r\n return this.pdf.title.endsWith('.pdf') ? this.pdf.title : `${this.pdf.title}.pdf`;\r\n }\r\n \r\n // Extract filename from src\r\n if (this.pdf.src) {\r\n const filename = this.pdf.src.split('/').pop() || 'PDF Document.pdf';\r\n return filename;\r\n }\r\n \r\n return 'PDF Document.pdf';\r\n }\r\n\r\n /**\r\n * Format file size for display\r\n */\r\n formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 Bytes';\r\n \r\n const k = 1024;\r\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n \r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n }\r\n\r\n /**\r\n * Share the PDF\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[PDF Lightbox] Share button clicked');\r\n \r\n if (!this.pdf?.src) return;\r\n \r\n try {\r\n await Share.share({\r\n title: this.pdf.title || 'PDF Document',\r\n text: this.pdf.description || '',\r\n url: this.pdf.src,\r\n dialogTitle: 'Share PDF'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF shared successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error sharing PDF:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Close the PDF viewer\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle like toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[PDF Lightbox] Like toggled');\r\n // TODO: Implement like logic for PDFs if needed\r\n }\r\n\r\n /**\r\n * Handle reply/comment\r\n * Close the lightbox and signal to open post detail with comment focus\r\n */\r\n onReply(): void {\r\n console.log('[PDF Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n // The calling code should handle opening the post detail modal\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable, ApplicationRef, ComponentRef, createComponent, EnvironmentInjector, Injector } from '@angular/core';\r\nimport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nimport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\n\r\n/**\r\n * Media file types supported by the lightbox\r\n */\r\nexport type LightboxMediaType = 'image' | 'pdf';\r\n\r\n/**\r\n * Base media file interface\r\n */\r\nexport interface LightboxMediaFile {\r\n /** File source URL */\r\n src: string;\r\n /** Media type - determines which viewer to use */\r\n type: LightboxMediaType;\r\n /** File title */\r\n title?: string;\r\n /** File description */\r\n description?: string;\r\n}\r\n\r\n/**\r\n * Image data for lightbox display\r\n */\r\nexport interface LightboxImage extends LightboxMediaFile {\r\n type: 'image';\r\n /** Alt text for accessibility */\r\n alt?: string;\r\n /** Thumbnail URL for faster loading (optional) */\r\n thumbnail?: string;\r\n /** Whether the image is liked */\r\n isLiked?: boolean;\r\n /** Number of likes */\r\n likeCount?: number;\r\n /** Number of comments */\r\n commentCount?: number;\r\n}\r\n\r\n/**\r\n * PDF document data for lightbox display\r\n */\r\nexport interface LightboxPdf extends LightboxMediaFile {\r\n type: 'pdf';\r\n /** File size in bytes (optional, for display) */\r\n fileSize?: number;\r\n /** Number of pages (optional, for display) */\r\n pageCount?: number;\r\n}\r\n\r\n/**\r\n * Author metadata for the lightbox\r\n */\r\nexport interface LightboxAuthor {\r\n /** Author name */\r\n name: string;\r\n /** Author role/subtitle */\r\n role?: string;\r\n /** Author avatar URL */\r\n avatarSrc?: string;\r\n /** Author avatar initials (if no photo) */\r\n avatarInitials?: string;\r\n /** Avatar type */\r\n avatarType?: 'photo' | 'initials';\r\n /** Timestamp */\r\n timestamp?: string;\r\n}\r\n\r\n/**\r\n * Configuration options for image lightbox\r\n */\r\nexport interface LightboxImageOptions {\r\n /** Array of images to display */\r\n images: LightboxImage[];\r\n /** Author information to display in header */\r\n author?: LightboxAuthor;\r\n /** Initial image index to show (0-based) */\r\n initialIndex?: number;\r\n /** Enable pinch-to-zoom and double-tap zoom */\r\n enableZoom?: boolean;\r\n /** Show navigation controls (arrows, counter) */\r\n showControls?: boolean;\r\n /** Enable swipe gestures to navigate between images */\r\n enableSwipe?: boolean;\r\n /** Show image info (title, description) */\r\n showInfo?: boolean;\r\n /** Animation type for opening */\r\n animation?: 'fade' | 'zoom' | 'slide';\r\n}\r\n\r\n/**\r\n * Configuration options for PDF lightbox\r\n */\r\nexport interface LightboxPdfOptions {\r\n /** PDF document to display */\r\n pdf: LightboxPdf;\r\n /** Author information to display */\r\n author?: LightboxAuthor;\r\n}\r\n\r\n/**\r\n * Generic lightbox options (for backward compatibility)\r\n */\r\nexport type LightboxOptions = LightboxImageOptions;\r\n\r\n/**\r\n * DsMobileLightboxService\r\n * \r\n * Service for displaying media files (images and PDFs) in full-screen viewers.\r\n * - Images: Full-screen modal with gestures (pinch-zoom, swipe navigation)\r\n * - PDFs: Native device PDF viewer (iOS/Android)\r\n * \r\n * Features:\r\n * - Full-screen image viewing with gestures\r\n * - Native PDF viewing\r\n * - Swipe navigation between images\r\n * - Pinch-to-zoom and double-tap zoom for images\r\n * - Mobile-optimized touch gestures\r\n * - Share functionality\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * // Open images\r\n * async openImages() {\r\n * const modal = await this.lightbox.openImages({\r\n * images: [\r\n * {\r\n * type: 'image',\r\n * src: 'https://example.com/image1.jpg',\r\n * title: 'Beautiful Sunset'\r\n * }\r\n * ]\r\n * });\r\n * \r\n * // Listen for when lightbox is dismissed\r\n * const { data } = await modal.onDidDismiss();\r\n * if (data?.action === 'comment') {\r\n * // Open post detail modal with comment focus\r\n * this.openPostDetail({ focusComment: true });\r\n * }\r\n * }\r\n * \r\n * // Open PDF\r\n * async openPdf() {\r\n * await this.lightbox.openPdf({\r\n * pdf: {\r\n * type: 'pdf',\r\n * src: 'https://example.com/document.pdf',\r\n * title: 'Document'\r\n * }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileLightboxService {\r\n private currentLightbox: ComponentRef<any> | null = null;\r\n\r\n constructor(\r\n private appRef: ApplicationRef,\r\n private injector: EnvironmentInjector\r\n ) {}\r\n\r\n /**\r\n * Open the lightbox with images (backward compatible method)\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async open(options: LightboxOptions): Promise<() => void> {\r\n return this.openImages(options);\r\n }\r\n\r\n /**\r\n * Open the image lightbox with one or more images\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openImages(options: LightboxImageOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening images with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxImageComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.images = options.images;\r\n componentRef.instance.author = options.author;\r\n componentRef.instance.initialIndex = options.initialIndex ?? 0;\r\n componentRef.instance.enableZoom = options.enableZoom !== false;\r\n componentRef.instance.showControls = options.showControls !== false;\r\n componentRef.instance.enableSwipe = options.enableSwipe !== false;\r\n componentRef.instance.showInfo = options.showInfo !== false;\r\n componentRef.instance.animation = options.animation ?? 'fade';\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] Image lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Open the PDF lightbox (opens native PDF viewer)\r\n * \r\n * @param options Configuration options for the PDF lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openPdf(options: LightboxPdfOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening PDF with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxPdfComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.pdf = options.pdf;\r\n componentRef.instance.author = options.author;\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] PDF lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Close the currently open lightbox\r\n */\r\n close(): void {\r\n if (this.currentLightbox) {\r\n const domElem = (this.currentLightbox.hostView as any).rootNodes[0] as HTMLElement;\r\n domElem.remove();\r\n this.appRef.detachView(this.currentLightbox.hostView);\r\n this.currentLightbox.destroy();\r\n this.currentLightbox = null;\r\n }\r\n }\r\n\r\n /**\r\n * Check if a lightbox is currently open\r\n */\r\n isOpen(): boolean {\r\n return this.currentLightbox !== null;\r\n }\r\n}\r\n\r\n","// Components\r\nexport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nexport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\nexport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nexport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\n\r\n// Service and Types\r\nexport { \r\n DsMobileLightboxService,\r\n type LightboxImage,\r\n type LightboxPdf,\r\n type LightboxMediaFile,\r\n type LightboxMediaType,\r\n type LightboxAuthor,\r\n type LightboxOptions,\r\n type LightboxImageOptions,\r\n type LightboxPdfOptions\r\n} from './ds-mobile-lightbox.service';\r\n\r\n// Legacy export for backward compatibility\r\nexport { DsMobileLightboxImageComponent as DsMobileLightboxComponent } from './ds-mobile-lightbox-image';\r\n\r\n","import { Component, Input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsMobileLightboxService, LightboxImage } from '../lightbox/ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileInlinePhotoComponent\r\n * \r\n * Displays one or multiple photos in a grid layout optimized for social feeds.\r\n * Supports up to 5 visible images with automatic grid layouts.\r\n * \r\n * Features:\r\n * - Automatic grid layouts for 1-5 images\r\n * - Shows \"+N more\" overlay if more than 5 images\r\n * - Opens lightbox with all images (including hidden ones) when clicked\r\n * - Optimized layouts: 1 full, 2 split, 3 masonry, 4 grid, 5 grid\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-inline-photo\r\n * [images]=\"['img1.jpg', 'img2.jpg', 'img3.jpg']\"\r\n * [author]=\"authorInfo\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-inline-photo',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div \r\n class=\"photo-grid\" \r\n [attr.data-count]=\"visibleImages.length\"\r\n [class.has-more]=\"hiddenCount > 0\">\r\n @for (image of visibleImages; track image; let i = $index) {\r\n <div \r\n class=\"photo-item\"\r\n [class.last]=\"i === visibleImages.length - 1\"\r\n (click)=\"openLightbox(i, $event)\">\r\n <img \r\n [src]=\"image\" \r\n [alt]=\"'Photo ' + (i + 1)\"\r\n loading=\"lazy\">\r\n \r\n <!-- Show \"+N more\" overlay on last image if there are hidden images -->\r\n @if (i === visibleImages.length - 1 && hiddenCount > 0) {\r\n <div class=\"more-overlay\">\r\n <span class=\"more-text\">+{{ hiddenCount }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n\r\n .photo-grid {\r\n display: grid;\r\n gap: 4px;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n background: var(--ds-color-neutral-100);\r\n width: 100%;\r\n }\r\n\r\n .photo-item {\r\n position: relative;\r\n overflow: hidden;\r\n cursor: pointer;\r\n background: var(--ds-color-neutral-200);\r\n aspect-ratio: 1;\r\n }\r\n\r\n .photo-item img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n display: block;\r\n transition: transform 0.2s ease;\r\n }\r\n\r\n .photo-item:active img {\r\n transform: scale(0.98);\r\n }\r\n\r\n .more-overlay {\r\n position: absolute;\r\n inset: 0;\r\n background: rgba(0, 0, 0, 0.6);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n pointer-events: none;\r\n }\r\n\r\n .more-text {\r\n color: white;\r\n font-size: 32px;\r\n font-weight: 600;\r\n font-family: var(--ds-font-family-medium);\r\n }\r\n\r\n /* 1 image: full width, 4:3 ratio */\r\n .photo-grid[data-count=\"1\"] {\r\n grid-template-columns: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"1\"] .photo-item {\r\n aspect-ratio: 4/3;\r\n }\r\n\r\n /* 2 images: side by side */\r\n .photo-grid[data-count=\"2\"] {\r\n grid-template-columns: 1fr 1fr;\r\n }\r\n\r\n /* 3 images: 1 large left, 2 stacked right */\r\n .photo-grid[data-count=\"3\"] {\r\n grid-template-columns: 2fr 1fr;\r\n grid-auto-rows: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"3\"] .photo-item:first-child {\r\n grid-row: 1 / 3;\r\n aspect-ratio: auto;\r\n }\r\n \r\n /* Right side images remain 1:1 squares */\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(2),\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(3) {\r\n aspect-ratio: 1;\r\n }\r\n\r\n /* 4 images: 2x2 grid */\r\n .photo-grid[data-count=\"4\"] {\r\n grid-template-columns: 1fr 1fr;\r\n grid-template-rows: 1fr 1fr;\r\n }\r\n\r\n /* 5 images: 2 on top, 3 on bottom */\r\n .photo-grid[data-count=\"5\"] {\r\n grid-template-columns: repeat(6, 1fr);\r\n grid-template-rows: auto auto;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item {\r\n aspect-ratio: 1;\r\n width: 100%;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(1) {\r\n grid-column: 1 / 4;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(2) {\r\n grid-column: 4 / 7;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n grid-column: 1 / 3;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(4) {\r\n grid-column: 3 / 5;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n grid-column: 5 / 7;\r\n grid-row: 2;\r\n }\r\n\r\n /* Round bottom corners for 5-image layout */\r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n border-bottom-left-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n border-bottom-right-radius: 8px;\r\n overflow: hidden;\r\n }\r\n `]\r\n})\r\nexport class DsMobileInlinePhotoComponent {\r\n /**\r\n * Array of image URLs to display\r\n */\r\n @Input() images: string[] = [];\r\n\r\n /**\r\n * Author information (passed to lightbox)\r\n */\r\n @Input() author?: {\r\n name: string;\r\n role?: string;\r\n avatarSrc?: string;\r\n avatarInitials?: string;\r\n avatarType?: 'photo' | 'initials';\r\n timestamp?: string;\r\n };\r\n\r\n /**\r\n * Maximum number of images to show inline (default: 5)\r\n * Remaining images shown in lightbox only\r\n */\r\n @Input() maxVisible: number = 5;\r\n\r\n /**\r\n * Event emitted when lightbox is opened\r\n */\r\n photoClick = output<{ index: number; totalImages: number }>();\r\n\r\n constructor(private lightboxService: DsMobileLightboxService) {}\r\n\r\n /**\r\n * Get the first N images to display inline\r\n */\r\n get visibleImages(): string[] {\r\n return this.images.slice(0, this.maxVisible);\r\n }\r\n\r\n /**\r\n * Calculate how many images are hidden\r\n */\r\n get hiddenCount(): number {\r\n return Math.max(0, this.images.length - this.maxVisible);\r\n }\r\n\r\n /**\r\n * Open lightbox with all images, starting at the clicked index\r\n */\r\n openLightbox(index: number, event?: Event): void {\r\n // Stop event propagation to prevent triggering parent click handlers\r\n if (event) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n }\r\n\r\n // Emit event\r\n this.photoClick.emit({\r\n index,\r\n totalImages: this.images.length\r\n });\r\n\r\n // Convert image URLs to LightboxImage format\r\n const lightboxImages: LightboxImage[] = this.images.map((src, i) => ({\r\n type: 'image',\r\n src,\r\n alt: `Photo ${i + 1}`\r\n }));\r\n\r\n // Open lightbox with all images (not just visible ones)\r\n this.lightboxService.openImages({\r\n images: lightboxImages,\r\n initialIndex: index,\r\n author: this.author,\r\n enableZoom: true,\r\n showControls: true,\r\n enableSwipe: true\r\n });\r\n }\r\n}\r\n\r\n","import { Injectable, Type } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Configuration options for modal presentation\r\n */\r\nexport interface ModalOptions<T = any> {\r\n /** The component to display in the modal */\r\n component: Type<T>;\r\n /** Props to pass to the component */\r\n componentProps?: Record<string, any>;\r\n /** CSS class(es) to apply to the modal */\r\n cssClass?: string | string[];\r\n /** Modal presentation style */\r\n presentationStyle?: 'fullscreen' | 'card' | 'sheet';\r\n /** Enable backdrop dismiss (tap outside to close) */\r\n backdropDismiss?: boolean;\r\n /** Show backdrop */\r\n showBackdrop?: boolean;\r\n /** Enable keyboard close (ESC key) */\r\n keyboardClose?: boolean;\r\n /** Enable swipe to close */\r\n swipeToClose?: boolean;\r\n /** Initial breakpoint (0-1) for sheet presentation */\r\n initialBreakpoint?: number;\r\n /** Available breakpoints for sheet presentation */\r\n breakpoints?: number[];\r\n /** Animation type */\r\n animated?: boolean;\r\n /** Mode (ios or md) */\r\n mode?: 'ios' | 'md';\r\n /** Whether to handle navigation back button */\r\n handleNavigationBack?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileModalService\r\n * \r\n * Generic service for displaying any component as a modal.\r\n * Built on Ionic's modal system with customizable presentation styles.\r\n * \r\n * Features:\r\n * - Open any component as a modal\r\n * - Fullscreen, card, or sheet presentation styles\r\n * - Customizable backdrop and dismissal behavior\r\n * - Native gestures and animations\r\n * - Type-safe component props\r\n * \r\n * @example\r\n * ```typescript\r\n * import { MobilePostDetailPageComponent } from './post-detail.page';\r\n * \r\n * constructor(private modal: DsMobileModalService) {}\r\n * \r\n * async openPostModal() {\r\n * await this.modal.open({\r\n * component: MobilePostDetailPageComponent,\r\n * componentProps: {\r\n * postId: '123',\r\n * authorName: 'John Doe'\r\n * },\r\n * presentationStyle: 'card',\r\n * backdropDismiss: true\r\n * });\r\n * }\r\n * ```\r\n * \r\n * @example Sheet presentation with breakpoints\r\n * ```typescript\r\n * async openSheet() {\r\n * await this.modal.open({\r\n * component: CommentsComponent,\r\n * presentationStyle: 'sheet',\r\n * initialBreakpoint: 0.5,\r\n * breakpoints: [0, 0.5, 0.75, 1],\r\n * swipeToClose: true\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open a component as a modal\r\n * \r\n * @param options Configuration options for the modal\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.open({\r\n * component: MyComponent,\r\n * componentProps: { data: 'value' },\r\n * presentationStyle: 'fullscreen'\r\n * });\r\n * ```\r\n */\r\n async open<T = any>(options: ModalOptions<T>): Promise<HTMLIonModalElement> {\r\n console.log('[Modal] Opening modal with options:', options);\r\n \r\n const {\r\n component,\r\n componentProps,\r\n cssClass,\r\n presentationStyle = 'card',\r\n backdropDismiss = true,\r\n showBackdrop = true,\r\n keyboardClose = true,\r\n swipeToClose,\r\n initialBreakpoint,\r\n breakpoints,\r\n animated = true,\r\n mode = 'ios',\r\n handleNavigationBack = true\r\n } = options;\r\n\r\n // Build modal configuration\r\n const modalConfig: any = {\r\n component,\r\n componentProps: componentProps || {},\r\n cssClass: this.buildCssClasses(cssClass, presentationStyle),\r\n mode,\r\n backdropDismiss,\r\n showBackdrop,\r\n animated,\r\n keyboardClose,\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n handle: presentationStyle === 'sheet', // Show handle for sheet presentation\r\n };\r\n\r\n // Add swipe to close for sheet presentation\r\n if (swipeToClose !== undefined) {\r\n modalConfig.canDismiss = swipeToClose;\r\n }\r\n\r\n // Add breakpoints for sheet presentation\r\n if (presentationStyle === 'sheet' && breakpoints) {\r\n modalConfig.breakpoints = breakpoints;\r\n if (initialBreakpoint !== undefined) {\r\n modalConfig.initialBreakpoint = initialBreakpoint;\r\n }\r\n }\r\n\r\n // Handle navigation back button\r\n if (handleNavigationBack) {\r\n modalConfig.canDismiss = async () => {\r\n // You can add custom logic here if needed\r\n return true;\r\n };\r\n }\r\n\r\n const modal = await this.modalController.create(modalConfig);\r\n\r\n console.log('[Modal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[Modal] Modal presented');\r\n\r\n return modal;\r\n }\r\n\r\n /**\r\n * Open a component as a fullscreen modal\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openFullscreen(PostDetailPage, { postId: '123' });\r\n * ```\r\n */\r\n async openFullscreen<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'fullscreen',\r\n backdropDismiss: false,\r\n showBackdrop: false\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a card modal\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openCard(DetailComponent, { itemId: '456' });\r\n * ```\r\n */\r\n async openCard<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'card',\r\n backdropDismiss: true,\r\n showBackdrop: true\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a bottom sheet\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @param options Additional sheet options (breakpoints, etc.)\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openSheet(\r\n * CommentsComponent,\r\n * { postId: '789' },\r\n * { initialBreakpoint: 0.5, breakpoints: [0, 0.5, 1] }\r\n * );\r\n * ```\r\n */\r\n async openSheet<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>,\r\n options?: {\r\n initialBreakpoint?: number;\r\n breakpoints?: number[];\r\n swipeToClose?: boolean;\r\n }\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'sheet',\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n swipeToClose: options?.swipeToClose ?? true,\r\n initialBreakpoint: options?.initialBreakpoint ?? 0.5,\r\n breakpoints: options?.breakpoints ?? [0, 0.5, 0.75, 1]\r\n });\r\n }\r\n\r\n /**\r\n * Close the currently open modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @param role Optional role (e.g., 'cancel', 'confirm')\r\n * @returns Promise that resolves when the modal is dismissed\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.dismiss({ saved: true }, 'confirm');\r\n * ```\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n * \r\n * @example\r\n * ```typescript\r\n * const topModal = await this.modal.getTop();\r\n * if (topModal) {\r\n * await topModal.dismiss();\r\n * }\r\n * ```\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n\r\n /**\r\n * Get all currently open modals\r\n * \r\n * @returns Promise that resolves to an array of modal elements\r\n */\r\n async getAll(): Promise<HTMLIonModalElement[]> {\r\n const modals: HTMLIonModalElement[] = [];\r\n let modal = await this.modalController.getTop();\r\n \r\n while (modal) {\r\n modals.push(modal);\r\n // Get the next modal in the stack\r\n await modal.dismiss();\r\n modal = await this.modalController.getTop();\r\n }\r\n \r\n return modals;\r\n }\r\n\r\n /**\r\n * Build CSS classes for the modal\r\n */\r\n private buildCssClasses(\r\n customClass?: string | string[],\r\n presentationStyle?: string\r\n ): string[] {\r\n const classes: string[] = ['ds-mobile-modal'];\r\n \r\n if (presentationStyle) {\r\n classes.push(`ds-modal-${presentationStyle}`);\r\n }\r\n \r\n if (customClass) {\r\n if (Array.isArray(customClass)) {\r\n classes.push(...customClass);\r\n } else {\r\n classes.push(customClass);\r\n }\r\n }\r\n \r\n return classes;\r\n }\r\n}\r\n\r\n","/**\r\n * Mobile Modal Module\r\n * \r\n * Generic service for opening any component as a modal\r\n */\r\n\r\nexport * from './ds-mobile-modal.service';\r\n\r\n","import {\r\n Component,\r\n signal,\r\n computed,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n Input,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport {\r\n IonContent,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport {\r\n DsMobilePostCardComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../post-card/ds-mobile-post-card';\r\nimport { DsMobileCommentComponent } from '../comment/ds-mobile-comment';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../lightbox';\r\nimport { \r\n DsMobileBottomSheetService, \r\n DsMobileCommentActionsBottomSheetComponent,\r\n CommentActionResult \r\n} from '../bottom-sheet';\r\n\r\n/**\r\n * Post data interface for the modal\r\n */\r\nexport interface PostDetailData {\r\n postId: string;\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarInitials?: string;\r\n avatarType?: 'photo' | 'initials';\r\n avatarSrc?: string;\r\n content: string;\r\n imageSrc?: string;\r\n imageAlt?: string;\r\n isLiked?: boolean;\r\n likeCount?: number;\r\n commentCount?: number;\r\n comments?: CommentData[];\r\n focusComment?: boolean; // Auto-focus comment input when modal opens\r\n}\r\n\r\nexport interface CommentData {\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarInitials: string;\r\n content: string;\r\n isLiked?: boolean;\r\n likeCount?: number;\r\n isOwnComment?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobilePostDetailModalComponent\r\n * \r\n * Modal wrapper for displaying post details with comments.\r\n * Follows the same pattern as the lightbox modal for consistent behavior.\r\n * \r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Image lightbox integration\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n * \r\n * This component is typically not used directly - use DsMobilePostDetailModalService instead.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n * \r\n * openPost() {\r\n * this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * content: 'Post content...'\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n DsIconButtonComponent,\r\n DsIconComponent,\r\n DsAvatarComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCommentComponent\r\n ],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content [fullscreen]=\"true\" [scrollY]=\"true\" class=\"post-modal-content\">\r\n <div class=\"post-modal-wrapper\">\r\n <!-- Header with post author info -->\r\n <div class=\"post-modal-header\">\r\n <div class=\"header-content\">\r\n <!-- Post author info -->\r\n <div class=\"post-author-info\">\r\n <ds-avatar\r\n [initials]=\"post().avatarInitials || ''\"\r\n [type]=\"post().avatarType || 'initials'\"\r\n [src]=\"post().avatarSrc || ''\"\r\n size=\"md\"\r\n />\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ post().authorName }}</div>\r\n <div class=\"author-meta\">\r\n <span>{{ post().authorRole }}</span>\r\n <span class=\"separator\">·</span>\r\n <span>{{ post().timestamp }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Luk opslag\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n\r\n <!-- Post content -->\r\n <div class=\"post-detail-container\">\r\n <!-- Post Section -->\r\n <div class=\"post-section\">\r\n <div class=\"post-content-only\">\r\n <post-text>{{ post().content }}</post-text>\r\n @if (post().imageSrc) {\r\n <post-media>\r\n <img \r\n [src]=\"post().imageSrc\"\r\n [alt]=\"post().imageAlt || 'Post image'\"\r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox()\"\r\n />\r\n </post-media>\r\n }\r\n </div>\r\n \r\n <!-- Post actions -->\r\n <div class=\"post-actions\">\r\n <action-like \r\n [active]=\"post().isLiked || false\" \r\n [count]=\"post().likeCount || 0\" />\r\n <action-comment \r\n [count]=\"post().commentCount || 0\"\r\n (commentClick)=\"focusCommentInput()\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Comments Section -->\r\n <div class=\"comments-section\">\r\n @if (post().comments && post().comments!.length > 0) {\r\n <h2 class=\"comments-header\">{{ post().comments!.length }} {{ post().comments!.length === 1 ? 'reply' : 'replies' }}</h2>\r\n \r\n <div class=\"comments-list\">\r\n @for (comment of post().comments!; track comment.authorName + comment.timestamp) {\r\n <ds-mobile-comment\r\n [authorName]=\"comment.authorName\"\r\n [authorRole]=\"comment.authorRole\"\r\n [timestamp]=\"comment.timestamp\"\r\n [avatarInitials]=\"comment.avatarInitials\"\r\n [content]=\"comment.content\"\r\n [isLiked]=\"comment.isLiked || false\"\r\n [likeCount]=\"comment.likeCount || 0\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"comment.isOwnComment || false\"\r\n (replyClick)=\"handleReply(comment.authorName, comment.content)\"\r\n (editClick)=\"handleEditComment(comment.authorName, comment.content, comment.timestamp)\"\r\n (longPress)=\"handleCommentLongPress(comment.authorName, comment.content, comment.isOwnComment || false)\" />\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"comments-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"Ingen kommentarer endnu\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">Ingen svar endnu</h3>\r\n <p class=\"empty-state-description\">Vær den første til at svare på dette opslag</p>\r\n </div>\r\n }\r\n \r\n <!-- Bottom spacer for fixed composer -->\r\n <div class=\"composer-spacer\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n \r\n <!-- Fixed comment composer -->\r\n <div class=\"comment-composer-fixed\">\r\n <div class=\"comment-composer\">\r\n <!-- Edit indicator -->\r\n @if (editingComment()) {\r\n <div class=\"edit-indicator\">\r\n <div class=\"edit-indicator-content\">\r\n <ds-icon name=\"remixEditLine\" size=\"16px\" />\r\n <span class=\"edit-text\">Redigerer kommentar</span>\r\n </div>\r\n <button class=\"cancel-edit\" (click)=\"cancelEdit()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n } @else if (replyingTo()) {\r\n <!-- Reply indicator -->\r\n <div class=\"reply-indicator\">\r\n <div class=\"reply-indicator-content\">\r\n <ds-icon name=\"remixReplyLine\" size=\"16px\" />\r\n <span class=\"reply-to-text\">\r\n Svarer til <span class=\"reply-author\">{{ replyingTo()!.authorName }}</span>\r\n </span>\r\n </div>\r\n <button class=\"cancel-reply\" (click)=\"cancelReply()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n }\r\n \r\n <div class=\"composer-content\">\r\n <ds-avatar\r\n [initials]=\"currentUserInitials()\"\r\n [type]=\"'initials'\"\r\n size=\"md\"\r\n />\r\n <div class=\"composer-input-wrapper\">\r\n <!-- Mention menu -->\r\n @if (showMentionMenu() && filteredUsers().length > 0 && !editingComment()) {\r\n <div class=\"mention-menu\">\r\n @for (user of filteredUsers(); track user.name) {\r\n <button \r\n class=\"mention-menu-item\" \r\n (click)=\"selectMention(user.name)\">\r\n <ds-avatar \r\n [initials]=\"user.initials\"\r\n [type]=\"'initials'\"\r\n size=\"sm\" />\r\n <div class=\"mention-user-info\">\r\n <span class=\"mention-user-name\">{{ user.name }}</span>\r\n <span class=\"mention-user-role\">{{ user.role }}</span>\r\n </div>\r\n </button>\r\n }\r\n </div>\r\n }\r\n \r\n <textarea\r\n #commentInput\r\n class=\"composer-input\"\r\n [placeholder]=\"editingComment() ? 'Rediger din kommentar...' : (replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...')\"\r\n [(ngModel)]=\"commentText\"\r\n (input)=\"handleInput($event)\"\r\n (focus)=\"showKeyboard()\"\r\n (click)=\"showKeyboard()\"\r\n rows=\"1\"\r\n ></textarea>\r\n </div>\r\n @if (commentText().trim().length > 0) {\r\n <ds-icon-button\r\n icon=\"remixCheckLine\"\r\n variant=\"primary\"\r\n size=\"sm\"\r\n (clicked)=\"submitComment()\"\r\n aria-label=\"Send kommentar\"\r\n class=\"send-button-fixed\">\r\n </ds-icon-button>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: relative;\r\n height: 100%;\r\n width: 100%;\r\n }\r\n\r\n .post-modal-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .post-modal-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n min-height: 100%;\r\n min-height: 100dvh; /* Use dynamic viewport height for proper iOS safe area handling */\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .post-modal-header {\r\n position: sticky;\r\n top: 0;\r\n z-index: 10;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 16px;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 72px;\r\n /* No padding needed - StatusBar.setOverlaysWebView(false) handles all spacing */\r\n }\r\n\r\n .post-author-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n /* Author name and meta styles imported from mobile-common.css */\r\n\r\n .author-meta .separator {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n\r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .post-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n width: 100%;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n padding: 16px 0 20px 0;\r\n flex: 1;\r\n }\r\n \r\n .post-section {\r\n width: 100%;\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 0 16px 0;\r\n }\r\n\r\n .post-content-only {\r\n font-size: var(--font-size-sm);\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin-bottom: 16px;\r\n padding: 0 20px;\r\n }\r\n \r\n .post-content-only post-media {\r\n margin-top: 16px;\r\n }\r\n\r\n .post-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 0 20px;\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n .comments-section {\r\n display: flex;\r\n flex-direction: column;\r\n margin-left: 0;\r\n margin-right: 0;\r\n padding: 0 20px;\r\n padding-bottom: 0;\r\n }\r\n \r\n .comments-header {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0 0 16px 0;\r\n padding-left: 0;\r\n padding-right: 0;\r\n }\r\n \r\n .comments-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Empty State */\r\n .comments-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n margin-bottom: 24px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0 0 8px 0;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-text-secondary, #737373);\r\n margin: 0;\r\n }\r\n \r\n .composer-spacer {\r\n /* Match full composer height:\r\n - Border: 1px\r\n - Top padding: 12px\r\n - Composer content: ~56px (avatar + input wrapper)\r\n - Bottom padding: 12px + safe area\r\n Total: ~81px + safe area */\r\n height: calc(81px + env(safe-area-inset-bottom, 0px));\r\n }\r\n \r\n .bottom-spacer {\r\n height: 0px;\r\n }\r\n\r\n /* Fixed Comment Composer Container */\r\n .comment-composer-fixed {\r\n position: fixed;\r\n bottom: 48px; /* Compensate for modal's margin-top: 48px */\r\n left: 0;\r\n right: 0;\r\n z-index: 1000;\r\n pointer-events: none;\r\n /* Slide up with keyboard on native apps */\r\n transform: translateY(calc(-1 * var(--keyboard-height, 0px)));\r\n transition: transform 0.3s ease-out;\r\n /* Ensure it's within the modal viewport */\r\n max-width: 100vw;\r\n }\r\n\r\n /* Comment Composer */\r\n .comment-composer {\r\n pointer-events: auto;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-top: 1px solid var(--border-color-default);\r\n padding: 12px 16px;\r\n /* Use dynamic viewport height safe area - matches tabs fix */\r\n /* For web browsers: 12px default; for native iOS: env(safe-area-inset-bottom) */\r\n padding-bottom: max(12px, env(safe-area-inset-bottom, 0px));\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n /* White box shadow to cover content gap between keyboard and composer */\r\n box-shadow: 100px 150px 0 150px var(--color-background-neutral-primary, #ffffff);\r\n }\r\n \r\n /* Edit indicator */\r\n .edit-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-brand-subtle, #f0edfe);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n \r\n .edit-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n color: var(--color-brand-base, #6B5FF5);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .edit-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-brand-base, #6B5FF5);\r\n }\r\n \r\n .cancel-edit {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-brand-base, #6B5FF5);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .cancel-edit:active {\r\n background: var(--color-brand-subtle, #e0dbfe);\r\n }\r\n \r\n /* Reply indicator */\r\n .reply-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n \r\n .reply-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n color: var(--color-text-secondary, #737373);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .reply-to-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .reply-author {\r\n color: var(--color-brand-base, #6B5FF5);\r\n font-weight: 600;\r\n }\r\n \r\n .cancel-reply {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-text-secondary, #737373);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .cancel-reply:active {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n @keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n \r\n .composer-content {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 12px;\r\n width: 100%;\r\n position: relative;\r\n }\r\n \r\n .composer-content ds-avatar {\r\n position: relative;\r\n top: 6px;\r\n }\r\n \r\n .composer-input-wrapper {\r\n flex: 1;\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 8px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 24px;\r\n padding: 12px 16px;\r\n padding-right: 48px; /* Extra padding for fixed send button */\r\n min-height: 44px;\r\n position: relative;\r\n }\r\n \r\n /* Mention menu */\r\n .mention-menu {\r\n position: absolute;\r\n bottom: 100%;\r\n left: 0;\r\n right: 0;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-radius: 12px;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n margin-bottom: 8px;\r\n max-height: 200px;\r\n overflow-y: auto;\r\n z-index: 10;\r\n animation: slideUp 0.2s ease-out;\r\n }\r\n \r\n @keyframes slideUp {\r\n from {\r\n opacity: 0;\r\n transform: translateY(10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n \r\n .mention-menu-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px;\r\n border: none;\r\n background: none;\r\n width: 100%;\r\n text-align: left;\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n border-bottom: 1px solid var(--border-color-default);\r\n }\r\n \r\n .mention-menu-item:last-child {\r\n border-bottom: none;\r\n }\r\n \r\n .mention-menu-item:active {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n .mention-user-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .mention-user-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .mention-user-role {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n \r\n .composer-input {\r\n flex: 1;\r\n border: none;\r\n background: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n outline: none;\r\n resize: none;\r\n min-height: 20px;\r\n max-height: 120px;\r\n overflow-y: auto;\r\n padding: 0;\r\n margin: 0;\r\n }\r\n \r\n .composer-input::placeholder {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n font-size: var(--font-size-sm);\r\n }\r\n \r\n /* Style the send button (ds-icon-button) - positioned in top right corner */\r\n .send-button-fixed {\r\n position: absolute;\r\n top: 6px;\r\n right: 6px;\r\n z-index: 10;\r\n flex-shrink: 0;\r\n animation: slideInFromRight 0.2s ease-out;\r\n }\r\n \r\n .send-button-fixed::ng-deep button {\r\n width: 32px !important;\r\n height: 32px !important;\r\n min-width: 32px !important;\r\n min-height: 32px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Keep old style for reference but won't be used */\r\n .composer-input-wrapper ds-icon-button {\r\n flex-shrink: 0;\r\n animation: slideInFromRight 0.2s ease-out;\r\n }\r\n \r\n .composer-input-wrapper ds-icon-button::ng-deep button {\r\n width: 32px !important;\r\n height: 32px !important;\r\n min-width: 32px !important;\r\n min-height: 32px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Slide in animation from right */\r\n @keyframes slideInFromRight {\r\n from {\r\n opacity: 0;\r\n transform: translateX(20px) scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0) scale(1);\r\n }\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .post-detail-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobilePostDetailModalComponent implements AfterViewInit, OnDestroy {\r\n // Post data passed from service\r\n @Input() postData!: PostDetailData;\r\n \r\n // ViewChild for comment input\r\n @ViewChild('commentInput') commentInput?: ElementRef<HTMLTextAreaElement>;\r\n\r\n // Signal for reactive post data\r\n post = signal<PostDetailData>({\r\n postId: '',\r\n authorName: '',\r\n authorRole: '',\r\n timestamp: '',\r\n content: '',\r\n comments: []\r\n });\r\n\r\n // Comment composer state\r\n commentText = signal('');\r\n currentUserInitials = signal('LM');\r\n replyingTo = signal<{ authorName: string; content: string } | null>(null);\r\n editingComment = signal<{ authorName: string; originalContent: string; timestamp: string } | null>(null);\r\n \r\n // Mention menu state\r\n showMentionMenu = signal(false);\r\n mentionQuery = signal('');\r\n \r\n // Get available users to mention (post author + commenters)\r\n availableUsers = computed(() => {\r\n const post = this.post();\r\n const users: Array<{ name: string; initials: string; role: string }> = [];\r\n \r\n // Add post author\r\n users.push({\r\n name: post.authorName,\r\n initials: post.avatarInitials || post.authorName.split(' ').map(n => n[0]).join(''),\r\n role: post.authorRole\r\n });\r\n \r\n // Add unique commenters\r\n const commenterNames = new Set<string>();\r\n post.comments?.forEach(comment => {\r\n if (!commenterNames.has(comment.authorName)) {\r\n commenterNames.add(comment.authorName);\r\n users.push({\r\n name: comment.authorName,\r\n initials: comment.avatarInitials,\r\n role: comment.authorRole\r\n });\r\n }\r\n });\r\n \r\n return users;\r\n });\r\n \r\n // Filtered users based on mention query\r\n filteredUsers = computed(() => {\r\n const query = this.mentionQuery().toLowerCase();\r\n if (!query) return this.availableUsers();\r\n return this.availableUsers().filter(user => \r\n user.name.toLowerCase().includes(query)\r\n );\r\n });\r\n\r\n constructor(\r\n private modalController: ModalController,\r\n private lightbox: DsMobileLightboxService,\r\n private bottomSheet: DsMobileBottomSheetService\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize post data from input\r\n if (this.postData) {\r\n this.post.set(this.postData);\r\n }\r\n \r\n // Set up keyboard listeners to update CSS variable for composer positioning\r\n this.setupKeyboardListeners();\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Auto-focus comment input if requested\r\n if (this.postData?.focusComment) {\r\n // Small delay to ensure modal animation is complete\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }, 300);\r\n }\r\n }\r\n \r\n ngOnDestroy(): void {\r\n // Clean up keyboard listeners when modal is destroyed\r\n this.cleanupKeyboardListeners();\r\n }\r\n \r\n /**\r\n * Set up keyboard event listeners to adjust composer position\r\n * The CSS uses --keyboard-height variable to translate the composer up\r\n */\r\n private setupKeyboardListeners(): void {\r\n Keyboard.addListener('keyboardWillShow', (info) => {\r\n document.documentElement.style.setProperty('--keyboard-height', `${info.keyboardHeight}px`);\r\n }).catch(e => console.log('Keyboard listeners not available:', e));\r\n \r\n Keyboard.addListener('keyboardWillHide', () => {\r\n document.documentElement.style.setProperty('--keyboard-height', '0px');\r\n }).catch(e => console.log('Keyboard listeners not available:', e));\r\n }\r\n \r\n /**\r\n * Clean up keyboard event listeners\r\n */\r\n private cleanupKeyboardListeners(): void {\r\n Keyboard.removeAllListeners().catch(e => console.log('Keyboard cleanup not available:', e));\r\n }\r\n\r\n /**\r\n * Show the keyboard when user interacts with input\r\n */\r\n showKeyboard(): void {\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }\r\n \r\n /**\r\n * Focus the comment input when comment icon is tapped\r\n */\r\n focusCommentInput(): void {\r\n // Focus the input\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }\r\n \r\n /**\r\n * Handle input changes and detect @ mentions\r\n */\r\n handleInput(event: Event): void {\r\n const textarea = event.target as HTMLTextAreaElement;\r\n const text = textarea.value;\r\n const cursorPosition = textarea.selectionStart || 0;\r\n \r\n // Auto-resize textarea\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n \r\n // Find the last @ before cursor\r\n const textBeforeCursor = text.substring(0, cursorPosition);\r\n const lastAtIndex = textBeforeCursor.lastIndexOf('@');\r\n \r\n if (lastAtIndex !== -1) {\r\n // Check if there's a space after @\r\n const textAfterAt = textBeforeCursor.substring(lastAtIndex + 1);\r\n const hasSpace = textAfterAt.includes(' ');\r\n \r\n if (!hasSpace) {\r\n // Show mention menu\r\n this.showMentionMenu.set(true);\r\n this.mentionQuery.set(textAfterAt);\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n }\r\n \r\n /**\r\n * Select a user from mention menu - show as reply indicator instead of inline mention\r\n */\r\n selectMention(userName: string): void {\r\n // Set as reply (similar to clicking Reply on a comment)\r\n this.replyingTo.set({ authorName: userName, content: '' });\r\n \r\n // Clear the @ from the input\r\n const currentText = this.commentText();\r\n const textWithoutMention = currentText.substring(0, currentText.lastIndexOf('@'));\r\n this.commentText.set(textWithoutMention);\r\n \r\n // Hide mention menu\r\n this.showMentionMenu.set(false);\r\n \r\n // Focus back on input\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n }, 0);\r\n }\r\n \r\n /**\r\n * Handle reply to a comment\r\n */\r\n handleReply(authorName: string, content: string): void {\r\n this.replyingTo.set({ authorName, content });\r\n // Focus the input and show keyboard\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n this.showKeyboard();\r\n }, 100);\r\n }\r\n \r\n /**\r\n * Cancel reply\r\n */\r\n cancelReply(): void {\r\n this.replyingTo.set(null);\r\n }\r\n \r\n /**\r\n * Cancel edit\r\n */\r\n cancelEdit(): void {\r\n this.editingComment.set(null);\r\n this.commentText.set('');\r\n }\r\n \r\n /**\r\n * Handle edit comment\r\n */\r\n handleEditComment(authorName: string, originalContent: string, timestamp: string): void {\r\n // Clear reply state if active\r\n this.replyingTo.set(null);\r\n \r\n // Remove @mention from the content if it exists\r\n let contentToEdit = originalContent;\r\n const mentionMatch = originalContent.match(/^@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\s+/);\r\n if (mentionMatch) {\r\n contentToEdit = originalContent.substring(mentionMatch[0].length);\r\n }\r\n \r\n // Set edit state\r\n this.editingComment.set({ authorName, originalContent, timestamp });\r\n \r\n // Populate the input with existing content\r\n this.commentText.set(contentToEdit);\r\n \r\n // Focus the input, show keyboard, and auto-resize\r\n setTimeout(() => {\r\n if (this.commentInput?.nativeElement) {\r\n const textarea = this.commentInput.nativeElement;\r\n textarea.focus();\r\n \r\n // Auto-resize textarea to fit content\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n \r\n this.showKeyboard();\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n\r\n /**\r\n * Submit a comment\r\n */\r\n submitComment(): void {\r\n const text = this.commentText().trim();\r\n if (!text) return;\r\n\r\n const currentPost = this.post();\r\n \r\n // Check if we're editing an existing comment\r\n if (this.editingComment()) {\r\n console.log('[PostDetailModal] Updating comment:', text);\r\n \r\n const editing = this.editingComment()!;\r\n \r\n // Update the existing comment\r\n const updatedComments = currentPost.comments?.map(comment => {\r\n if (comment.authorName === editing.authorName && \r\n comment.content === editing.originalContent &&\r\n comment.timestamp === editing.timestamp) {\r\n return {\r\n ...comment,\r\n content: text,\r\n timestamp: 'Just now (edited)'\r\n };\r\n }\r\n return comment;\r\n });\r\n \r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments\r\n });\r\n \r\n // Clear edit state\r\n this.editingComment.set(null);\r\n } else {\r\n // Create new comment\r\n console.log('[PostDetailModal] Submitting comment:', text);\r\n \r\n const newComment: CommentData = {\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'You',\r\n timestamp: 'Just now',\r\n avatarInitials: this.currentUserInitials(),\r\n content: this.replyingTo() \r\n ? `@${this.replyingTo()!.authorName} ${text}`\r\n : text,\r\n isLiked: false,\r\n likeCount: 0,\r\n isOwnComment: true\r\n };\r\n\r\n // Add comment to the list\r\n const updatedComments = [...(currentPost.comments || []), newComment];\r\n \r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments,\r\n commentCount: updatedComments.length\r\n });\r\n \r\n // Clear reply state\r\n this.replyingTo.set(null);\r\n }\r\n\r\n // Clear the input\r\n this.commentText.set('');\r\n this.showMentionMenu.set(false);\r\n \r\n // Reset textarea height to initial state\r\n if (this.commentInput?.nativeElement) {\r\n this.commentInput.nativeElement.style.height = 'auto';\r\n }\r\n \r\n // Blur the input to hide the keyboard\r\n this.commentInput?.nativeElement.blur();\r\n \r\n // Hide keyboard explicitly\r\n Keyboard.hide().catch(e => console.log('Keyboard.hide() not available'));\r\n\r\n // In a real app, you would also send this to your backend\r\n // this.commentService.addComment(currentPost.postId, text);\r\n }\r\n\r\n /**\r\n * Open image in lightbox\r\n */\r\n openImageLightbox(): void {\r\n const postData = this.post();\r\n \r\n if (!postData.imageSrc) return;\r\n\r\n const authorMeta: LightboxAuthor = {\r\n name: postData.authorName,\r\n role: postData.authorRole,\r\n avatarInitials: postData.avatarInitials || '',\r\n avatarType: postData.avatarType || 'initials',\r\n avatarSrc: postData.avatarSrc || '',\r\n timestamp: postData.timestamp\r\n };\r\n\r\n this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: postData.imageSrc,\r\n alt: postData.imageAlt || 'Post image',\r\n title: postData.imageAlt || '',\r\n description: postData.content,\r\n isLiked: postData.isLiked || false,\r\n likeCount: postData.likeCount || 0,\r\n commentCount: postData.commentCount || 0\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false,\r\n showInfo: true\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a comment to show action sheet\r\n */\r\n async handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobileCommentActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnComment\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as CommentActionResult).action;\r\n const currentPost = this.post();\r\n \r\n switch (action) {\r\n case 'like':\r\n console.log('Like comment by', authorName);\r\n // Find and toggle like on the comment\r\n const updatedComments = currentPost.comments?.map(comment => {\r\n if (comment.authorName === authorName && comment.content === content) {\r\n const isLiked = !comment.isLiked;\r\n return {\r\n ...comment,\r\n isLiked,\r\n likeCount: isLiked ? (comment.likeCount || 0) + 1 : Math.max(0, (comment.likeCount || 0) - 1)\r\n };\r\n }\r\n return comment;\r\n });\r\n this.post.set({ ...currentPost, comments: updatedComments });\r\n break;\r\n case 'reply':\r\n console.log('Reply to comment by', authorName);\r\n this.handleReply(authorName, content);\r\n break;\r\n case 'edit':\r\n console.log('Edit comment by', authorName);\r\n // Find the full comment data to get timestamp\r\n const commentToEdit = currentPost.comments?.find(\r\n comment => comment.authorName === authorName && comment.content === content\r\n );\r\n if (commentToEdit) {\r\n this.handleEditComment(authorName, content, commentToEdit.timestamp);\r\n }\r\n break;\r\n case 'delete':\r\n console.log('Delete comment by', authorName);\r\n // Show confirmation before deleting\r\n if (confirm('Are you sure you want to delete this comment?')) {\r\n const updatedCommentsAfterDelete = currentPost.comments?.filter(\r\n comment => !(comment.authorName === authorName && comment.content === content)\r\n );\r\n this.post.set({ \r\n ...currentPost, \r\n comments: updatedCommentsAfterDelete,\r\n commentCount: updatedCommentsAfterDelete?.length || 0\r\n });\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobilePostDetailModalComponent, PostDetailData } from './ds-mobile-post-detail-modal';\r\n\r\n/**\r\n * DsMobilePostDetailModalService\r\n * \r\n * Service for displaying post details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * Follows the same pattern as DsMobileLightboxService for consistent behavior.\r\n * \r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Like/comment actions\r\n * - Image lightbox integration\r\n * - Native modal animations\r\n * - Safe area support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n * \r\n * async openPost() {\r\n * await this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * authorRole: 'Tenant',\r\n * timestamp: '2h ago',\r\n * avatarInitials: 'JD',\r\n * content: 'Just moved into my new apartment!',\r\n * isLiked: false,\r\n * likeCount: 42,\r\n * commentCount: 12,\r\n * comments: [\r\n * {\r\n * authorName: 'Jane Smith',\r\n * authorRole: 'Tenant',\r\n * timestamp: '1h ago',\r\n * avatarInitials: 'JS',\r\n * content: 'Welcome to the community!'\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobilePostDetailModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the post detail modal\r\n * \r\n * @param postData Post data to display\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(postData: PostDetailData): Promise<void> {\r\n console.log('[PostDetailModal] Opening with data:', postData);\r\n \r\n const modal = await this.modalController.create({\r\n component: DsMobilePostDetailModalComponent,\r\n componentProps: {\r\n postData: postData\r\n },\r\n cssClass: 'ds-post-detail-modal',\r\n mode: 'ios',\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n // Control the presenting element animation\r\n enterAnimation: undefined, // Use default\r\n leaveAnimation: undefined // Use default\r\n });\r\n\r\n console.log('[PostDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[PostDetailModal] Modal presented');\r\n }\r\n\r\n /**\r\n * Close the currently open post detail modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","/**\r\n * Mobile Post Detail Modal Module\r\n * \r\n * Service and component for displaying posts in a modal\r\n */\r\n\r\nexport * from './ds-mobile-post-detail-modal';\r\nexport * from './ds-mobile-post-detail-modal.service';\r\n\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileHandbookFolderMiniComponent\r\n * \r\n * A minimized folder icon component for use in headers and small spaces.\r\n * Simplified version without animations or page sheets - just folder and icon.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder-mini\r\n * [variant]=\"'pink'\"\r\n * [iconName]=\"'remixLightbulbLine'\">\r\n * </ds-mobile-handbook-folder-mini>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder-mini',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n width: 32px;\r\n height: 32px;\r\n flex-shrink: 0;\r\n }\r\n \r\n .mini-folder-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n .mini-folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n .mini-folder-back {\r\n height: 28px;\r\n border-radius: 0px 4px 4px 4px;\r\n position: relative;\r\n margin-top: -1px;\r\n }\r\n \r\n .mini-folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 24px;\r\n border-radius: 4px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 2;\r\n box-shadow: inset 0 8px 8px rgba(255, 255, 255, 0.2), \r\n inset 0 0.5px 0.5px rgba(255, 255, 255, 0.3);\r\n }\r\n `],\r\n template: `\r\n <div class=\"mini-folder-container\">\r\n <!-- Folder Tab SVG -->\r\n <svg \r\n class=\"mini-folder-tab\" \r\n width=\"101\" \r\n height=\"24\" \r\n viewBox=\"0 0 101 24\" \r\n fill=\"none\" \r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path \r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\" \r\n [attr.fill]=\"getColorVar('strong')\"/>\r\n </svg>\r\n \r\n <!-- Folder Back -->\r\n <div class=\"mini-folder-back\" [style.background-color]=\"getColorVar('strong')\">\r\n <!-- Folder Front -->\r\n <div \r\n class=\"mini-folder-front\" \r\n [style.background-color]=\"getColorVar('base')\">\r\n <ds-icon \r\n [name]=\"iconName\" \r\n [size]=\"'14px'\"\r\n [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileHandbookFolderMiniComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n */\r\n @Input() variant: string = 'light-purple';\r\n \r\n /**\r\n * Icon name from the design system icon library\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n \r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n 'success': 'success',\r\n 'warning': 'warning',\r\n 'destructive': 'destructive',\r\n 'blue': 'blue',\r\n 'light-purple': 'light-purple',\r\n 'pink': 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n 'orange': 'orange',\r\n 'lime-green': 'lime-green',\r\n 'grey': 'grey'\r\n };\r\n \r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileFileAttachmentComponent\r\n * \r\n * File attachment display for various document types.\r\n * Shows file info card with icon, filename, and file size.\r\n * Supports PDF and generic document formats.\r\n * Emits click event to open file in viewer.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-file-attachment\r\n * [fileName]=\"'Document.pdf'\"\r\n * [fileSize]=\"'1.2 MB'\"\r\n * [variant]=\"'pdf'\"\r\n * (fileClick)=\"openFile()\">\r\n * </ds-mobile-file-attachment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-file-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .file-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .file-avatar.pdf::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .file-avatar.doc::ng-deep .avatar--icon {\r\n background-color: var(--color-blue-base, #3B82F6) !important;\r\n }\r\n \r\n .file-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .file-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .file-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"file-avatar\" [class.pdf]=\"variant() === 'pdf'\" [class.doc]=\"variant() === 'doc'\">\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"getIconName()\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"file-info\">\r\n <div class=\"file-name\">{{ fileName() }}</div>\r\n @if (fileSize()) {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>\r\n } @else {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }}</div>\r\n }\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"20px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class DsMobileFileAttachmentComponent {\r\n /**\r\n * File name\r\n */\r\n fileName = input<string>('Document');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * File type variant\r\n * - 'pdf' - PDF document (red icon)\r\n * - 'doc' - Generic document (blue icon)\r\n */\r\n variant = input<'pdf' | 'doc'>('doc');\r\n \r\n /**\r\n * Emits when the file attachment is clicked\r\n */\r\n fileClick = output<void>();\r\n \r\n /**\r\n * Get the appropriate icon name based on variant\r\n */\r\n getIconName(): string {\r\n return this.variant() === 'pdf' ? 'remixFileTextLine' : 'remixAttachmentLine';\r\n }\r\n \r\n /**\r\n * Get the file type label based on variant\r\n */\r\n getFileTypeLabel(): string {\r\n return this.variant() === 'pdf' ? 'PDF' : 'DOC';\r\n }\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.fileClick.emit();\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n input,\r\n AfterViewInit,\r\n OnDestroy,\r\n ElementRef,\r\n ViewChild,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport Swiper from 'swiper';\r\n\r\n/**\r\n * DsMobileSwiperComponent\r\n * \r\n * A reusable swiper/carousel component with configurable child width and spacing.\r\n * \r\n * Features:\r\n * - First slide is left-aligned\r\n * - Middle slides are centered when active\r\n * - Last slide is right-aligned\r\n * - Configurable slide width and gap\r\n * - Content projection via ng-content\r\n * \r\n * Usage:\r\n * ```html\r\n * <ds-mobile-swiper [slideWidth]=\"'75vw'\" [gap]=\"16\">\r\n * <div class=\"swiper-slide\">Slide 1</div>\r\n * <div class=\"swiper-slide\">Slide 2</div>\r\n * <div class=\"swiper-slide\">Slide 3</div>\r\n * </ds-mobile-swiper>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-swiper',\r\n standalone: true,\r\n imports: [CommonModule],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .swiper-container {\r\n width: 100%;\r\n position: relative;\r\n overflow: hidden;\r\n border-radius: 12px;\r\n }\r\n\r\n .swiper-wrapper {\r\n display: flex;\r\n transition-property: transform;\r\n box-sizing: content-box;\r\n }\r\n\r\n :host ::ng-deep .swiper-slide {\r\n flex-shrink: 0;\r\n height: 100%;\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n `]\r\n})\r\nexport class DsMobileSwiperComponent implements AfterViewInit, OnDestroy {\r\n /**\r\n * Width of each slide (e.g., '75vw', '300px', '80%')\r\n */\r\n slideWidth = input<string>('75vw');\r\n\r\n /**\r\n * Gap between slides in pixels\r\n */\r\n gap = input<number>(16);\r\n\r\n @ViewChild('swiperContainer', { static: false }) swiperContainer!: ElementRef;\r\n\r\n private swiperInstance: Swiper | null = null;\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n }, 100);\r\n }\r\n\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) return;\r\n\r\n // Apply slide width to all slides\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.swiper-slide');\r\n slides.forEach((slide: HTMLElement) => {\r\n slide.style.width = this.slideWidth();\r\n });\r\n\r\n this.swiperInstance = new Swiper(this.swiperContainer.nativeElement, {\r\n slidesPerView: 'auto',\r\n spaceBetween: this.gap(),\r\n centeredSlides: true,\r\n centeredSlidesBounds: true,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.swiperInstance) {\r\n this.swiperInstance.destroy();\r\n this.swiperInstance = null;\r\n }\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n signal,\r\n Input,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonContent,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileHandbookFolderMiniComponent } from '../handbook-folder/ds-mobile-handbook-folder-mini';\r\nimport { DsMobileFileAttachmentComponent } from '../file-attachment';\r\nimport { DsMobileContactListItemComponent } from '../contact-list-item';\r\nimport { DsMobileSwiperComponent } from '../swiper';\r\n\r\n/**\r\n * Handbook detail data interface\r\n */\r\nexport interface HandbookDetailData {\r\n title: string;\r\n variant: string;\r\n iconName: string;\r\n itemCount: number;\r\n items?: HandbookItem[];\r\n}\r\n\r\nexport interface HandbookItem {\r\n title: string;\r\n description?: string;\r\n images?: string[];\r\n attachments?: AttachmentItem[];\r\n contacts?: ContactItem[];\r\n}\r\n\r\nexport interface AttachmentItem {\r\n name: string;\r\n type?: string;\r\n}\r\n\r\nexport interface ContactItem {\r\n name: string;\r\n initials: string;\r\n contactPerson?: string;\r\n phoneNumber?: string;\r\n}\r\n\r\n/**\r\n * DsMobileHandbookDetailModalComponent\r\n * \r\n * Modal wrapper for displaying handbook folder details.\r\n * \r\n * Features:\r\n * - Folder content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n * \r\n * This component is typically not used directly - use DsMobileHandbookDetailModalService instead.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonContent,\r\n DsIconButtonComponent,\r\n DsMobileHandbookFolderMiniComponent,\r\n DsMobileFileAttachmentComponent,\r\n DsMobileContactListItemComponent,\r\n DsMobileSwiperComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content [fullscreen]=\"true\" [scrollY]=\"true\" class=\"handbook-modal-content\">\r\n <div class=\"handbook-modal-wrapper\">\r\n <!-- Header -->\r\n <div class=\"handbook-modal-header\">\r\n <div class=\"header-content\">\r\n <!-- Handbook folder info -->\r\n <div class=\"handbook-folder-info\">\r\n <ds-mobile-handbook-folder-mini\r\n [variant]=\"handbook().variant\"\r\n [iconName]=\"handbook().iconName\">\r\n </ds-mobile-handbook-folder-mini>\r\n <div class=\"folder-details\">\r\n <div class=\"folder-name\">{{ handbook().title }}</div>\r\n <div class=\"folder-meta\">\r\n <span>{{ handbook().itemCount }} emner</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Luk\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"handbook-detail-container\">\r\n @if (handbook().items && handbook().items!.length > 0) {\r\n @for (item of getDisplayItems(); track item.title + $index; let isLast = $last) {\r\n <div class=\"handbook-item\" [class.last-item]=\"isLast\">\r\n <div class=\"item-text-group\">\r\n <h2 class=\"item-title\">{{ item.title }}</h2>\r\n \r\n @if (item.description) {\r\n <p class=\"item-description\">{{ item.description }}</p>\r\n }\r\n </div>\r\n \r\n <!-- Images -->\r\n @if (item.images && item.images.length > 0) {\r\n <ds-mobile-swiper [slideWidth]=\"item.images.length === 1 ? '100%' : '60vw'\" [gap]=\"16\">\r\n @for (image of item.images; track image) {\r\n <div class=\"swiper-slide\">\r\n <img \r\n [src]=\"image\" \r\n [alt]=\"item.title\"\r\n class=\"item-image\"\r\n />\r\n </div>\r\n }\r\n </ds-mobile-swiper>\r\n }\r\n \r\n <!-- Contacts -->\r\n @if (item.contacts && item.contacts.length > 0) {\r\n <div class=\"contacts-list\">\r\n @for (contact of item.contacts; track contact.name) {\r\n <ds-mobile-contact-list-item\r\n [name]=\"contact.name\"\r\n [initials]=\"contact.initials\"\r\n [contactPerson]=\"contact.contactPerson || ''\"\r\n [phoneNumber]=\"contact.phoneNumber || ''\"\r\n [clickable]=\"true\"\r\n (contactClick)=\"handleContactClick(contact)\">\r\n </ds-mobile-contact-list-item>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Attachments -->\r\n @if (item.attachments && item.attachments.length > 0) {\r\n <div class=\"attachments-list\">\r\n @for (attachment of item.attachments; track attachment.name) {\r\n <ds-mobile-file-attachment\r\n [fileName]=\"attachment.name\"\r\n [variant]=\"attachment.type === 'pdf' ? 'pdf' : 'doc'\"\r\n (fileClick)=\"handleAttachmentClick(attachment)\">\r\n </ds-mobile-file-attachment>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"handbook-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"No items yet\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">No items yet</h3>\r\n <p class=\"empty-state-description\">This folder is empty</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ion-content>\r\n `,\r\n styles: [`\r\n .handbook-modal-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .handbook-modal-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n min-height: 100%;\r\n min-height: 100dvh;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .handbook-modal-header {\r\n position: sticky;\r\n top: 0;\r\n z-index: 10;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 16px;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 72px;\r\n }\r\n\r\n .handbook-folder-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .folder-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n .folder-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n\r\n .folder-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n\r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .handbook-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n flex: 1;\r\n }\r\n \r\n .handbook-item {\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 24px;\r\n padding: 24px 20px 24px 20px;\r\n border-bottom: 1px solid var(--border-color-default);\r\n }\r\n \r\n .handbook-item.last-item {\r\n border-bottom: none;\r\n }\r\n\r\n .item-text-group {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n\r\n .item-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 16px;\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n }\r\n\r\n .item-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n }\r\n\r\n .item-image {\r\n width: 100%;\r\n height: 280px;\r\n object-fit: cover;\r\n border-radius: 12px;\r\n display: block;\r\n }\r\n\r\n .contacts-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:last-child) {\r\n position: relative;\r\n padding-bottom: 8px;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:first-child) {\r\n padding-top: 8px;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:last-child)::after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: 44px;\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n \r\n .attachments-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n \r\n\r\n /* Empty State */\r\n .handbook-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .handbook-detail-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileHandbookDetailModalComponent {\r\n // Handbook data passed from service\r\n @Input() handbookData!: HandbookDetailData;\r\n \r\n // Signal for reactive handbook data\r\n handbook = signal<HandbookDetailData>({\r\n title: '',\r\n variant: 'light-purple',\r\n iconName: 'remixFolder3Line',\r\n itemCount: 0,\r\n items: []\r\n });\r\n\r\n constructor(\r\n private modalController: ModalController\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize handbook data from input\r\n if (this.handbookData) {\r\n this.handbook.set(this.handbookData);\r\n }\r\n }\r\n\r\n /**\r\n * Split handbook items to enforce content structure rules:\r\n * - Never mix photos and documents (attachments) in the same section\r\n * - Never mix contact persons and attachments together in the same section\r\n * \r\n * This method splits items that violate these rules into multiple display items.\r\n * Each resulting item will have only compatible content types.\r\n */\r\n splitItemsByContentRules(item: HandbookItem): HandbookItem[] {\r\n const displayItems: HandbookItem[] = [];\r\n \r\n const hasImages = item.images && item.images.length > 0;\r\n const hasContacts = item.contacts && item.contacts.length > 0;\r\n const hasAttachments = item.attachments && item.attachments.length > 0;\r\n \r\n // Case 1: Only one type of content - keep as is\r\n const contentTypeCount = [hasImages, hasContacts, hasAttachments].filter(Boolean).length;\r\n if (contentTypeCount <= 1) {\r\n return [item];\r\n }\r\n \r\n // Case 2: Has images + contacts (allowed together) but no attachments\r\n if (hasImages && hasContacts && !hasAttachments) {\r\n return [item];\r\n }\r\n \r\n // Case 3: Violates rules - need to split\r\n \r\n // First item: Text + Images (if present)\r\n if (hasImages) {\r\n displayItems.push({\r\n title: item.title,\r\n description: item.description,\r\n images: item.images\r\n });\r\n }\r\n \r\n // Second item: Text + Contacts (if present and no images shown yet)\r\n if (hasContacts) {\r\n displayItems.push({\r\n title: item.title,\r\n description: hasImages ? undefined : item.description, // Only show description if not shown before\r\n contacts: item.contacts\r\n });\r\n }\r\n \r\n // Third item: Text + Attachments (if present)\r\n if (hasAttachments) {\r\n displayItems.push({\r\n title: item.title,\r\n description: (!hasImages && !hasContacts) ? item.description : undefined, // Only show description if not shown before\r\n attachments: item.attachments\r\n });\r\n }\r\n \r\n return displayItems;\r\n }\r\n \r\n /**\r\n * Get all display items with enforced content structure rules applied\r\n */\r\n getDisplayItems(): HandbookItem[] {\r\n const items = this.handbook().items || [];\r\n const displayItems: HandbookItem[] = [];\r\n \r\n for (const item of items) {\r\n const splitItems = this.splitItemsByContentRules(item);\r\n displayItems.push(...splitItems);\r\n }\r\n \r\n return displayItems;\r\n }\r\n\r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n \r\n /**\r\n * Handle contact click\r\n */\r\n handleContactClick(contact: ContactItem): void {\r\n console.log('Contact clicked:', contact);\r\n // Implement contact action (e.g., show contact details, call, etc.)\r\n }\r\n \r\n /**\r\n * Handle attachment click\r\n */\r\n handleAttachmentClick(attachment: AttachmentItem): void {\r\n console.log('Attachment clicked:', attachment);\r\n // Implement attachment action (e.g., open file viewer, download, etc.)\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileHandbookDetailModalComponent, HandbookDetailData } from './ds-mobile-handbook-detail-modal';\r\n\r\n/**\r\n * DsMobileHandbookDetailModalService\r\n * \r\n * Service for displaying handbook folder details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * \r\n * Features:\r\n * - Full handbook content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal animations\r\n * - Safe area support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private handbookModal: DsMobileHandbookDetailModalService) {}\r\n * \r\n * async openHandbook() {\r\n * await this.handbookModal.open({\r\n * title: 'Utilities',\r\n * variant: 'pink',\r\n * iconName: 'remixLightbulbLine',\r\n * itemCount: 8,\r\n * items: [\r\n * {\r\n * title: 'Hjertestarter',\r\n * description: 'Installed on the 4th floor...',\r\n * images: ['/path/to/image.jpg'],\r\n * contacts: [\r\n * { name: 'Mortensen & Søn ApS', initials: 'M' }\r\n * ]\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileHandbookDetailModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the handbook detail modal\r\n * \r\n * @param handbookData Handbook data to display\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(handbookData: HandbookDetailData): Promise<void> {\r\n console.log('[HandbookDetailModal] Opening with data:', handbookData);\r\n \r\n const modal = await this.modalController.create({\r\n component: DsMobileHandbookDetailModalComponent,\r\n componentProps: {\r\n handbookData: handbookData\r\n },\r\n cssClass: 'ds-handbook-detail-modal',\r\n mode: 'ios',\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n enterAnimation: undefined,\r\n leaveAnimation: undefined\r\n });\r\n\r\n console.log('[HandbookDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[HandbookDetailModal] Modal presented');\r\n }\r\n\r\n /**\r\n * Close the currently open handbook detail modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","import { Component, Input, signal, HostListener } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileHandbookDetailModalService, HandbookDetailData, HandbookItem } from '../handbook-detail-modal';\r\n\r\n/**\r\n * DsMobileHandbookFolderComponent\r\n * \r\n * A visually rich folder component for displaying handbook categories or sections.\r\n * Features a two-layer folder design with customizable colors, icon, item count, and label.\r\n * \r\n * Design Details:\r\n * - Folder back: 72px height with a decorative notch\r\n * - Folder front: 64px height overlaying the back\r\n * - Item count displayed in bottom-left corner\r\n * - Icon displayed in bottom-right corner\r\n * - Label text centered below the folder\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder\r\n * [colorBase]=\"'#d244cf'\"\r\n * [colorWeak]=\"'#f9e6f9'\"\r\n * [iconName]=\"'remixLightbulbLine'\"\r\n * [itemCount]=\"8\"\r\n * [label]=\"'Utilities'\">\r\n * </ds-mobile-handbook-folder>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n :host {\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 16px;\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n padding: 16px;\r\n border-radius: 16px;\r\n background: var(--color-background-neutral-secondary, #f0f0f0);\r\n transition: background 0.2s ease;\r\n }\r\n \r\n :host:active {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n @media (hover: hover) {\r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n }\r\n \r\n .folder-container {\r\n position: relative;\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n perspective: 800px;\r\n -webkit-perspective: 800px;\r\n max-width: 160px;\r\n /* Safari optimization: Ensure proper 3D rendering context */\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n }\r\n \r\n .folder-container.open .page-sheet {\r\n -webkit-transform: translateY(-8px);\r\n transform: translateY(-8px);\r\n transition-delay: 0.2s;\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(1) {\r\n -webkit-transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(2) {\r\n -webkit-transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(3) {\r\n -webkit-transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(4) {\r\n -webkit-transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(5) {\r\n -webkit-transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(6) {\r\n -webkit-transform: scale(0.90) translateY(-28px) rotateX(0deg) translateZ(0.1px);\r\n transform: scale(0.90) translateY(-28px) rotateX(0.1px);\r\n }\r\n \r\n .folder-container.open .folder-front {\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n }\r\n \r\n .folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n .folder-back {\r\n height: 128px;\r\n border-radius: 0px 12px 12px 12px;\r\n position: relative;\r\n margin-top: -1px;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Force GPU acceleration */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n }\r\n \r\n .page-sheet {\r\n position: absolute;\r\n width: 80%;\r\n height: 120px;\r\n background: #ffffff;\r\n border-radius: 8px;\r\n box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);\r\n border: 1px solid var(--border-color-default);\r\n transition: transform 0.3s ease-out;\r\n -webkit-transition: -webkit-transform 0.3s ease-out;\r\n left: 10%;\r\n /* Safari optimization: Force hardware acceleration and proper 3D rendering */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Prevent subpixel rendering issues */\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Ensure proper layer creation */\r\n will-change: transform;\r\n }\r\n \r\n .page-sheet:nth-child(1) {\r\n bottom: 2px;\r\n z-index: 6;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(1) translateZ(0.1px);\r\n transform: scale(1) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(2) {\r\n bottom: 8px;\r\n z-index: 5;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.98) translateZ(0.1px);\r\n transform: scale(0.98) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(3) {\r\n bottom: 14px;\r\n z-index: 4;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.96) translateZ(0.1px);\r\n transform: scale(0.96) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(4) {\r\n bottom: 20px;\r\n z-index: 3;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.94) translateZ(0.1px);\r\n transform: scale(0.94) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(5) {\r\n bottom: 26px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.92) translateZ(0.1px);\r\n transform: scale(0.92) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(6) {\r\n bottom: 32px;\r\n z-index: 1;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.90) translateZ(0.1px);\r\n transform: scale(0.90) translateZ(0.1px);\r\n }\r\n \r\n .folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 116px;\r\n border-radius: 12px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 8px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n transition: transform 0.4s ease-in-out, -webkit-transform 0.4s ease-in-out;\r\n -webkit-transition: -webkit-transform 0.4s ease-in-out;\r\n will-change: transform;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Use more specific transform to avoid render glitches */\r\n -webkit-transform: rotateX(-20deg) translateZ(0.1px);\r\n transform: rotateX(-20deg) translateZ(0.1px);\r\n /* Safari optimization: Force layer creation for smoother animations */\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n box-shadow: inset 0 64px 48px rgba(255, 255, 255, 0.2), \r\n inset 0 2px 4px rgba(255, 255, 255, 0.3),\r\n inset 0 1px 1px rgba(255, 255, 255, 0.3);\r\n }\r\n \r\n .item-count {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n \r\n .item-count-label {\r\n letter-spacing: 0.5px;\r\n }\r\n \r\n .folder-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .folder-label-container {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n \r\n .folder-label {\r\n text-align: center;\r\n }\r\n `],\r\n template: `\r\n <div class=\"folder-container\" \r\n [class.open]=\"isOpen()\">\r\n <!-- Folder Tab SVG -->\r\n <svg \r\n class=\"folder-tab\" \r\n width=\"101\" \r\n height=\"24\" \r\n viewBox=\"0 0 101 24\" \r\n fill=\"none\" \r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path \r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\" \r\n [attr.fill]=\"getColorVar('strong')\"/>\r\n </svg>\r\n \r\n <!-- Folder Back -->\r\n <div class=\"folder-back\" [style.background-color]=\"getColorVar('strong')\">\r\n <!-- Page Sheets -->\r\n @for (sheet of getPageSheets(); track $index) {\r\n <div class=\"page-sheet\"></div>\r\n }\r\n \r\n <!-- Folder Front -->\r\n <div \r\n class=\"folder-front\" \r\n [style.--border-color]=\"getColorVar('strong')\"\r\n [style.background-color]=\"getColorVar('base')\">\r\n <!-- Icon (Centered) -->\r\n <div class=\"folder-icon\">\r\n <ds-icon \r\n [name]=\"iconName\" \r\n [size]=\"'32px'\"\r\n [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Label and Item Count -->\r\n <div class=\"folder-label-container\">\r\n <div class=\"folder-label ui-sm-semiBold\">{{ label }}</div>\r\n <div class=\"item-count ui-sm-regular\" [style.color]=\"'var(--color-text-secondary, #6b7280)'\">\r\n <span>{{ itemCount }}</span>\r\n <span class=\"item-count-label\">emner</span>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileHandbookFolderComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n * Example: 'pink', 'success', 'blue'\r\n */\r\n @Input() variant: string = 'light-purple';\r\n \r\n /**\r\n * Icon name from the design system icon library\r\n * Example: 'remixLightbulbLine', 'remixFolder3Line'\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n \r\n /**\r\n * Number of items in the folder\r\n */\r\n @Input() itemCount: number = 0;\r\n \r\n /**\r\n * Label text displayed below the folder\r\n */\r\n @Input() label: string = 'Folder';\r\n \r\n /**\r\n * Optional items data for the handbook folder\r\n */\r\n @Input() items?: HandbookItem[];\r\n \r\n /**\r\n * Track open/closed state for animation\r\n */\r\n isOpen = signal(false);\r\n \r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n 'success': 'success',\r\n 'warning': 'warning',\r\n 'destructive': 'destructive',\r\n 'blue': 'blue',\r\n 'light-purple': 'light-purple',\r\n 'pink': 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n 'orange': 'orange',\r\n 'lime-green': 'lime-green',\r\n 'grey': 'grey'\r\n };\r\n \r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n \r\n /**\r\n * Open folder animation\r\n */\r\n @HostListener('mouseenter')\r\n open(): void {\r\n this.isOpen.set(true);\r\n }\r\n \r\n /**\r\n * Close folder animation\r\n */\r\n @HostListener('mouseleave')\r\n close(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle touch start - open animation\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n onTouchStart(event: TouchEvent): void {\r\n this.isOpen.set(true);\r\n }\r\n \r\n /**\r\n * Handle touch end - close animation\r\n */\r\n @HostListener('touchend')\r\n onTouchEnd(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle touch cancel - close animation\r\n */\r\n @HostListener('touchcancel')\r\n onTouchCancel(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle click - open modal\r\n */\r\n @HostListener('click')\r\n async onClick(): Promise<void> {\r\n const handbookData: HandbookDetailData = {\r\n title: this.label,\r\n variant: this.variant,\r\n iconName: this.iconName,\r\n itemCount: this.itemCount,\r\n items: this.items\r\n };\r\n\r\n await this.handbookModal.open(handbookData);\r\n }\r\n \r\n /**\r\n * Calculate the number of page sheets to display\r\n * Max 6 sheets regardless of item count\r\n */\r\n getPageSheets(): number[] {\r\n const count = Math.min(this.itemCount, 6);\r\n return Array(count).fill(0);\r\n }\r\n\r\n constructor(\r\n private handbookModal: DsMobileHandbookDetailModalService\r\n ) {}\r\n}\r\n\r\n","// Mobile Page Components\r\nexport * from './page-main';\r\nexport * from './page-details';\r\n\r\n// Mobile Content Components\r\nexport * from './content';\r\nexport * from './header-content';\r\n\r\n// Mobile Community Components\r\nexport * from './post-card';\r\nexport * from './comment';\r\nexport * from './post-composer';\r\n\r\n// Mobile List Components\r\nexport * from './list-item';\r\nexport { DsMobileInteractiveListItemPostComponent, PostPdfAttachmentComponent } from './interactive-list-item-post';\r\nexport { DsMobileInteractiveListItemInquiryComponent } from './interactive-list-item-inquiry';\r\nexport { DsMobileInteractiveListItemMessageComponent } from './interactive-list-item-message';\r\nexport { DsMobileContactListItemComponent } from './contact-list-item';\r\n\r\n// Mobile Layout Components\r\nexport { DsMobileAppLayoutComponent, type HeaderVariant } from './app-layout';\r\nexport { DsMobileTabsComponent, type TabConfig } from './tabs';\r\n\r\n// Mobile Bottom Sheet Components\r\nexport * from './bottom-sheet';\r\n\r\n// Mobile Lightbox Components\r\nexport * from './lightbox';\r\n\r\n// Mobile Inline Photo Component\r\nexport * from './inline-photo';\r\n\r\n// Mobile Modal Service\r\nexport * from './modal';\r\n\r\n// Mobile Post Detail Modal\r\nexport * from './post-detail-modal';\r\n\r\n// Mobile Handbook Components\r\nexport * from './handbook-folder';\r\nexport * from './handbook-detail-modal';\r\n\r\n// Shared directives\r\nexport * from './shared';","import { Injectable, signal } from '@angular/core';\r\n\r\n/**\r\n * User service for managing current user data globally\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class UserService {\r\n // User avatar configuration\r\n private _avatarInitials = signal('LM');\r\n private _avatarType = signal<'initials' | 'photo' | 'icon'>('initials');\r\n private _avatarSrc = signal('');\r\n \r\n // Readonly computed values\r\n readonly avatarInitials = this._avatarInitials.asReadonly();\r\n readonly avatarType = this._avatarType.asReadonly();\r\n readonly avatarSrc = this._avatarSrc.asReadonly();\r\n \r\n /**\r\n * Update avatar configuration\r\n */\r\n setAvatarInitials(initials: string) {\r\n this._avatarInitials.set(initials);\r\n }\r\n \r\n setAvatarType(type: 'initials' | 'photo' | 'icon') {\r\n this._avatarType.set(type);\r\n }\r\n \r\n setAvatarSrc(src: string) {\r\n this._avatarSrc.set(src);\r\n }\r\n}\r\n\r\n","import { Component, signal, computed } from '@angular/core';\r\nimport { Router, ActivatedRoute } from '@angular/router';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileContentComponent } from '../components/content';\r\nimport { DsMobileInteractiveListItemPostComponent, PostPdfAttachmentComponent } from '../components/interactive-list-item-post';\r\nimport { \r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../components/interactive-list-item-post';\r\nimport { DsMobilePostComposerComponent } from '../components/post-composer';\r\nimport { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';\r\nimport { DsMobilePostCreateBottomSheetComponent } from '../components/bottom-sheet/ds-mobile-post-create-bottom-sheet';\r\nimport { DsMobilePostActionsBottomSheetComponent, PostActionResult } from '../components/bottom-sheet';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../components/lightbox';\r\nimport { DsMobilePostDetailModalService } from '../components/post-detail-modal';\r\nimport { DsMobileInlinePhotoComponent } from '../components/inline-photo';\r\nimport { UserService } from '../services/user.service';\r\n\r\n@Component({\r\n selector: 'app-mobile-community-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileContentComponent,\r\n DsMobileInteractiveListItemPostComponent,\r\n DsMobilePostComposerComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n PostPdfAttachmentComponent,\r\n DsIconComponent,\r\n DsMobileInlinePhotoComponent\r\n ],\r\n styles: [`\r\n .post-feed {\r\n display: flex;\r\n flex-direction: column;\r\n max-width: 640px;\r\n }\r\n \r\n .post-list-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Remove custom dividers - now handled by ds-mobile-list-item */\r\n \r\n .pinned-posts-section {\r\n margin: -12px -12px 12px -12px;\r\n padding: 0 12px 12px 12px;\r\n box-shadow: var(--box-shadow-sm);\r\n border-radius: 16px;\r\n border: 1px solid var(--border-color-default);\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n /* Empty State */\r\n .community-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n margin-bottom: 24px;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Fællesskab\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <!-- Post Composer in header-expandable -->\r\n <ds-mobile-post-composer\r\n header-content\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n [avatarSrc]=\"userService.avatarSrc()\"\r\n (composerClick)=\"openPostCreator()\"\r\n />\r\n \r\n <ds-mobile-content>\r\n <div class=\"post-feed\">\r\n <!-- Pinned Posts Section -->\r\n <div class=\"pinned-posts-section\">\r\n <h2 class=\"section-headline\">\r\n <ds-icon name=\"remixPushpinFill\" size=\"16px\" color=\"primary\" />\r\n Fastgjorte opslag\r\n </h2>\r\n \r\n <!-- Pinned: Maintenance Announcement -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Karen Nielsen'\"\r\n [authorRole]=\"'Ejendomsadministrator'\"\r\n [timestamp]=\"'2d siden'\"\r\n [avatarInitials]=\"'KN'\"\r\n [showBadge]=\"true\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('4')\"\r\n (commentClick)=\"openPost('4', true)\"\r\n (longPress)=\"handlePostLongPress('4', false)\">\r\n \r\n <post-content>\r\n <post-text>📢 Påmindelse: Bygningsvedligeholdelse planlagt til denne lørdag fra kl. 9 til 14. Vandet vil være midlertidigt lukket. Vær venlig at planlægge derefter!</post-text>\r\n \r\n <post-attachments>\r\n <post-pdf-attachment\r\n [fileName]=\"'Husregler.pdf'\"\r\n [fileSize]=\"'245 KB'\"\r\n (pdfClick)=\"openHouseRulesPdf()\">\r\n </post-pdf-attachment>\r\n </post-attachments>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"89\" />\r\n <action-comment [count]=\"67\" (commentClick)=\"openPost('4', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n </div>\r\n \r\n <!-- All Posts Section -->\r\n <h2 class=\"section-headline\">Alle opslag</h2>\r\n \r\n @if (hasAnyPosts()) {\r\n <div class=\"post-list-wrapper\">\r\n <!-- User Created Posts -->\r\n @for (post of userPosts(); track $index) {\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"post.authorName\"\r\n [authorRole]=\"post.authorRole\"\r\n [timestamp]=\"post.timestamp\"\r\n [avatarType]=\"post.avatarType\"\r\n [avatarSrc]=\"post.avatarSrc\"\r\n [avatarInitials]=\"post.avatarInitials\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openUserPost($index)\"\r\n (commentClick)=\"openUserPost($index, true)\"\r\n (longPress)=\"handlePostLongPress($index, post.authorRole === 'Dig')\">\r\n \r\n <post-content>\r\n @if (post.content) {\r\n <post-text>{{ post.content }}</post-text>\r\n }\r\n @if (post.imageSrc) {\r\n <post-media>\r\n <img \r\n [src]=\"post.imageSrc\" \r\n [alt]=\"post.imageAlt || 'Posted image'\" \r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox(post.imageSrc, post.imageAlt || 'Posted image', post.content, $event)\"\r\n />\r\n </post-media>\r\n }\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"post.likeCount\" [active]=\"post.isLiked\" />\r\n <action-comment [count]=\"post.commentCount\" (commentClick)=\"openUserPost($index, true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n }\r\n \r\n <!-- Post 1: Text only -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Anders Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarType]=\"'photo'\"\r\n [avatarSrc]=\"'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('1')\"\r\n (commentClick)=\"openPost('1', true)\"\r\n (longPress)=\"handlePostLongPress('1', false)\">\r\n \r\n <post-content>\r\n <post-text>Lige flyttet ind i min nye lejlighed! Udlejeren var super hjælpsom gennem hele processen. Virkelig begejstret for at være en del af dette fællesskab! 🏠</post-text>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"42\" />\r\n <action-comment [count]=\"12\" (commentClick)=\"openPost('1', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 2: With multiple images (grid layout) -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Sophie Andersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'4t siden'\"\r\n [avatarInitials]=\"'SA'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('2')\"\r\n (commentClick)=\"openPost('2', true)\"\r\n (longPress)=\"handlePostLongPress('2', false)\">\r\n \r\n <post-content>\r\n <post-text>Jeg har taget nogle billeder af vores smukke ejendom i løbet af det sidste par måneder. Fra altanudsigten om morgenen til den nye trappe og fællesområderne. Elsker virkelig at bo her! 🏡✨</post-text>\r\n <ds-mobile-inline-photo\r\n [images]=\"[\r\n '/Assets/Dummy-photos/balcony-view.jpg',\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/yard.jpg'\r\n ]\"\r\n [author]=\"{\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n avatarType: 'initials',\r\n timestamp: '4t siden'\r\n }\"\r\n />\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [active]=\"true\" [count]=\"156\" />\r\n <action-comment [count]=\"34\" (commentClick)=\"openPost('2', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 3: Question -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Thomas Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1d siden'\"\r\n [avatarType]=\"'photo'\"\r\n [avatarSrc]=\"'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('3')\"\r\n (commentClick)=\"openPost('3', true)\"\r\n (longPress)=\"handlePostLongPress('3', false)\">\r\n \r\n <post-content>\r\n <post-text>Kender nogen et fælles fitnesscenter i nærheden? Leder efter anbefalinger til gode træningscentre i området. 🏋️</post-text>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"23\" />\r\n <action-comment [count]=\"45\" (commentClick)=\"openPost('3', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 3.5: Property Manager showcase with 6+ photos -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Karen Nielsen'\"\r\n [authorRole]=\"'Ejendomsadministrator'\"\r\n [timestamp]=\"'2d siden'\"\r\n [avatarInitials]=\"'KN'\"\r\n [showBadge]=\"true\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('3.5')\"\r\n (commentClick)=\"openPost('3.5', true)\"\r\n (longPress)=\"handlePostLongPress('3.5', false)\">\r\n \r\n <post-content>\r\n <post-text>Her er et kig på vores nyligt renoverede fællesområder! Vi har opgraderet postkasserne, trappeafsatsen og gårdområdet. Der er også blevet ansat en ny vicevært. Glæd dig over forbedringerne! 🏢✨</post-text>\r\n <ds-mobile-inline-photo\r\n [images]=\"[\r\n '/Assets/Dummy-photos/mailboxes.jpg',\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/yard.jpg',\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/balcony-view.jpg',\r\n '/Assets/Dummy-photos/handyman.jpg'\r\n ]\"\r\n [author]=\"{\r\n name: 'Karen Nielsen',\r\n role: 'Ejendomsadministrator',\r\n avatarInitials: 'KN',\r\n avatarType: 'initials',\r\n timestamp: '2d siden'\r\n }\"\r\n [maxVisible]=\"5\"\r\n />\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"234\" />\r\n <action-comment [count]=\"89\" (commentClick)=\"openPost('3.5', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n\r\n <!-- Post 5: Event -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Emma Petersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3d siden'\"\r\n [avatarType]=\"'photo'\"\r\n [avatarSrc]=\"'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face'\"\r\n [clickable]=\"true\"\r\n (postClick)=\"openPost('5')\"\r\n (commentClick)=\"openPost('5', true)\"\r\n (longPress)=\"handlePostLongPress('5', false)\">\r\n \r\n <post-content>\r\n <post-text>Arrangerer en fælles BBQ næste weekend! Alle er inviteret. Tag din yndlingsret med til at dele. Lad os lære hinanden bedre at kende! 🍔🌭</post-text>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [active]=\"true\" [count]=\"124\" />\r\n <action-comment [count]=\"89\" (commentClick)=\"openPost('5', true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n </div>\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"community-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"Ingen opslag endnu\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">Ingen opslag endnu</h3>\r\n <p class=\"empty-state-description\">Vær den første til at dele noget med dit fællesskab</p>\r\n </div>\r\n }\r\n </div>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileCommunityPageComponent {\r\n // Store user-created posts\r\n userPosts = signal<any[]>([\r\n {\r\n id: 'user-post-1',\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: '5m siden',\r\n avatarType: 'initials' as 'photo' | 'initials' | 'icon',\r\n avatarInitials: 'LM',\r\n content: 'Dette er mit første opslag! Ser frem til at forbinde med alle i bygningen. 🏠',\r\n isLiked: false,\r\n likeCount: 3,\r\n commentCount: 1\r\n }\r\n ]);\r\n \r\n // Flag to control whether static demo posts are shown\r\n // Set to false to see the empty state\r\n showStaticPosts = signal(true);\r\n \r\n // Computed to check if there are any posts to display\r\n hasAnyPosts = computed(() => {\r\n return this.userPosts().length > 0 || this.showStaticPosts();\r\n });\r\n \r\n constructor(\r\n private router: Router,\r\n private route: ActivatedRoute,\r\n private bottomSheet: DsMobileBottomSheetService,\r\n private lightbox: DsMobileLightboxService,\r\n private postModal: DsMobilePostDetailModalService,\r\n public userService: UserService\r\n ) {}\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n /**\r\n * Open post detail modal\r\n * This provides a better UX than route navigation:\r\n * - Maintains scroll position\r\n * - Native iOS-style modal feel\r\n * - Proper close button that works\r\n */\r\n async openPost(postId: string, focusComment: boolean = false): Promise<void> {\r\n console.log('[Community] ===== openPost called =====', postId, 'Focus comment:', focusComment);\r\n \r\n // Map post ID to post data (in real app, fetch from service)\r\n const postDataMap: Record<string, any> = {\r\n '1': {\r\n postId: '1',\r\n authorName: 'Anders Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '2t siden',\r\n avatarType: 'photo' as const,\r\n avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face',\r\n content: 'Lige flyttet ind i min nye lejlighed! Udlejeren var super hjælpsom gennem hele processen. Virkelig begejstret for at være en del af dette fællesskab! 🏠',\r\n isLiked: false,\r\n likeCount: 42,\r\n commentCount: 12,\r\n comments: [\r\n {\r\n authorName: 'Mette Larsen',\r\n authorRole: 'Lejer',\r\n timestamp: '1t siden',\r\n avatarInitials: 'ML',\r\n content: 'Velkommen til fællesskabet!',\r\n likeCount: 5,\r\n isOwnComment: false\r\n },\r\n {\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarInitials: 'LM',\r\n content: 'Vxhknbh',\r\n likeCount: 0,\r\n isOwnComment: true\r\n }\r\n ]\r\n },\r\n '2': {\r\n postId: '2',\r\n authorName: 'Sophie Andersen',\r\n authorRole: 'Lejer',\r\n timestamp: '4t siden',\r\n avatarInitials: 'SA',\r\n content: 'Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️',\r\n imageSrc: '/Assets/Dummy-photos/balcony-view.jpg',\r\n imageAlt: 'Altanudsigt',\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34,\r\n comments: [\r\n {\r\n authorName: 'Anders Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '3t siden',\r\n avatarInitials: 'AJ',\r\n content: 'Wow, den udsigt er fantastisk! Hvilken etage er du på?',\r\n likeCount: 12,\r\n isOwnComment: false\r\n },\r\n {\r\n authorName: 'Thomas Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '3t siden',\r\n avatarInitials: 'TH',\r\n content: 'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆',\r\n isLiked: true,\r\n likeCount: 8,\r\n isOwnComment: false\r\n },\r\n {\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarInitials: 'LM',\r\n content: 'Vxhknbh',\r\n likeCount: 0,\r\n isOwnComment: true\r\n }\r\n ]\r\n },\r\n '3': {\r\n postId: '3',\r\n authorName: 'Thomas Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '1d siden',\r\n avatarType: 'photo' as const,\r\n avatarSrc: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face',\r\n content: 'Kender nogen et fælles fitnesscenter i nærheden? Leder efter anbefalinger til gode træningscentre i området. 🏋️',\r\n isLiked: false,\r\n likeCount: 23,\r\n commentCount: 45,\r\n comments: []\r\n },\r\n '4': {\r\n postId: '4',\r\n authorName: 'Karen Nielsen',\r\n authorRole: 'Ejendomsadministrator',\r\n timestamp: '2d siden',\r\n avatarInitials: 'KN',\r\n content: '📢 Påmindelse: Bygningsvedligeholdelse planlagt til denne lørdag fra kl. 9 til 14. Vandet vil være midlertidigt lukket. Vær venlig at planlægge derefter!',\r\n isLiked: false,\r\n likeCount: 89,\r\n commentCount: 67,\r\n comments: []\r\n },\r\n '5': {\r\n postId: '5',\r\n authorName: 'Emma Petersen',\r\n authorRole: 'Lejer',\r\n timestamp: '3d siden',\r\n avatarType: 'photo' as const,\r\n avatarSrc: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face',\r\n content: 'Arrangerer en fælles BBQ næste weekend! Alle er inviteret. Tag din yndlingsret med til at dele. Lad os lære hinanden bedre at kende! 🍔🌭',\r\n isLiked: true,\r\n likeCount: 124,\r\n commentCount: 89,\r\n comments: []\r\n }\r\n };\r\n\r\n const postData = postDataMap[postId];\r\n \r\n if (postData) {\r\n // Add focusComment flag to postData\r\n await this.postModal.open({ ...postData, focusComment });\r\n }\r\n }\r\n \r\n /**\r\n * Open user-created post detail modal\r\n */\r\n async openUserPost(index: number, focusComment: boolean = false): Promise<void> {\r\n const posts = this.userPosts();\r\n const post = posts[index];\r\n \r\n if (post) {\r\n console.log('[Community] Opening user post modal:', index, 'Focus comment:', focusComment);\r\n \r\n // Convert user post to modal format with empty comments array\r\n const postData = {\r\n ...post,\r\n postId: `user-${index}`,\r\n comments: [] // User posts don't have comments yet\r\n };\r\n \r\n await this.postModal.open({ ...postData, focusComment });\r\n }\r\n }\r\n \r\n async openPostCreator(): Promise<void> {\r\n // Open the post creator as a bottom sheet modal\r\n // Using 95% initial height to maximize keyboard auto-open chances\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobilePostCreateBottomSheetComponent,\r\n componentProps: {\r\n // This helps the component know it should auto-focus\r\n autoFocus: true\r\n },\r\n breakpoints: [0, 0.95, 1],\r\n initialBreakpoint: 0.95,\r\n handle: true\r\n });\r\n \r\n // Handle the result when the sheet is dismissed\r\n const result = await sheet.onWillDismiss();\r\n if (result.role === 'post' && result.data) {\r\n console.log('New post created:', result.data);\r\n \r\n // Create a new post object\r\n const newPost = {\r\n id: `user-post-${Date.now()}`, // Generate unique ID\r\n authorName: 'Lars Mikkelsen', // Current user name\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarType: this.userService.avatarType() as 'photo' | 'initials' | 'icon',\r\n avatarSrc: this.userService.avatarSrc(),\r\n avatarInitials: this.userService.avatarInitials(),\r\n content: result.data.content,\r\n imageSrc: result.data.images && result.data.images.length > 0 ? result.data.images[0] : undefined,\r\n imageAlt: result.data.images && result.data.images.length > 0 ? 'Slået billede op' : undefined,\r\n isLiked: false,\r\n likeCount: 0,\r\n commentCount: 0\r\n };\r\n \r\n // Add to the beginning of the posts array\r\n this.userPosts.update(posts => [newPost, ...posts]);\r\n }\r\n }\r\n \r\n /**\r\n * Open an image in the lightbox viewer\r\n * Prevents the post click event from firing\r\n */\r\n async openImageLightbox(imageSrc: string, title: string, description: string, event: Event): Promise<void> {\r\n console.log('[Community] Opening lightbox for image:', imageSrc);\r\n \r\n // Prevent the post card click event from firing\r\n event.stopPropagation();\r\n \r\n const authorMeta: LightboxAuthor = {\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n timestamp: '4t siden'\r\n };\r\n \r\n // Open the lightbox with the image\r\n await this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: imageSrc,\r\n alt: title,\r\n title: title,\r\n description: description,\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false, // Single image, no need for controls\r\n showInfo: true\r\n });\r\n }\r\n\r\n async openHouseRulesPdf(): Promise<void> {\r\n console.log('[Community] Opening House Rules PDF');\r\n \r\n // Author metadata\r\n const authorMeta: LightboxAuthor = {\r\n name: 'Karen Nielsen',\r\n role: 'Ejendomsadministrator',\r\n avatarInitials: 'KN',\r\n timestamp: '2d siden'\r\n };\r\n \r\n // Open the PDF lightbox\r\n // Use absolute path for production deployment (Vercel, etc.)\r\n await this.lightbox.openPdf({\r\n pdf: {\r\n type: 'pdf',\r\n src: '/Assets/House_Rules.pdf', // Capital A to match public/Assets folder structure\r\n title: 'House Rules',\r\n description: 'Building regulations and community guidelines',\r\n fileSize: 250880, // 245 KB in bytes\r\n pageCount: 8\r\n },\r\n author: authorMeta\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a post to show action sheet\r\n */\r\n async handlePostLongPress(postIdOrIndex: string | number, isOwnPost: boolean): Promise<void> {\r\n console.log('[Community] Post long pressed:', postIdOrIndex, 'isOwn:', isOwnPost);\r\n \r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobilePostActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnPost\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as PostActionResult).action;\r\n \r\n switch (action) {\r\n case 'edit':\r\n console.log('Edit post:', postIdOrIndex);\r\n // Open the post create bottom sheet in edit mode\r\n let postContent = '';\r\n let postId = '';\r\n \r\n // Get post content based on postIdOrIndex\r\n if (typeof postIdOrIndex === 'number') {\r\n const post = this.userPosts()[postIdOrIndex];\r\n if (post) {\r\n postContent = post.content || '';\r\n postId = post.id || postIdOrIndex.toString();\r\n }\r\n } else {\r\n // For static posts, we'll need to determine content\r\n // For now, use a placeholder\r\n postId = postIdOrIndex.toString();\r\n postContent = 'Edit this post...';\r\n }\r\n \r\n // Open the bottom sheet in edit mode\r\n const editSheet = await this.bottomSheet.create({\r\n component: DsMobilePostCreateBottomSheetComponent,\r\n componentProps: {\r\n autoFocus: true,\r\n isEditMode: true,\r\n postId: postId,\r\n initialContent: postContent\r\n },\r\n breakpoints: [0, 0.95, 1],\r\n initialBreakpoint: 0.95,\r\n handle: true,\r\n backdropBlur: true,\r\n backdropOpacity: 0.6\r\n });\r\n \r\n // Handle the result when the sheet is dismissed\r\n const editResult = await editSheet.onWillDismiss();\r\n if (editResult.role === 'post' && editResult.data) {\r\n console.log('Post updated:', editResult.data);\r\n \r\n // Update the post in the array\r\n if (typeof postIdOrIndex === 'number') {\r\n const currentPosts = this.userPosts();\r\n const updatedPosts = currentPosts.map((post, index) => \r\n index === postIdOrIndex \r\n ? { ...post, content: editResult.data.content, timestamp: 'Just now' }\r\n : post\r\n );\r\n this.userPosts.set(updatedPosts);\r\n }\r\n }\r\n break;\r\n case 'delete':\r\n console.log('Delete post:', postIdOrIndex);\r\n if (confirm('Er du sikker på, at du vil slette dette opslag?')) {\r\n // If it's a user post (number index), remove it from the array\r\n if (typeof postIdOrIndex === 'number') {\r\n const currentPosts = this.userPosts();\r\n const updatedPosts = currentPosts.filter((_, index) => index !== postIdOrIndex);\r\n this.userPosts.set(updatedPosts);\r\n }\r\n // Otherwise it's a static post, just show confirmation\r\n else {\r\n alert('Opslag slettet!');\r\n }\r\n }\r\n break;\r\n case 'like':\r\n console.log('Like post:', postIdOrIndex);\r\n // Toggle like - in a real app, this would call an API\r\n alert('Opslag liket!');\r\n break;\r\n case 'reply':\r\n console.log('Reply to post:', postIdOrIndex);\r\n // Open the post detail modal with comment input focused\r\n if (typeof postIdOrIndex === 'number') {\r\n await this.openUserPost(postIdOrIndex, true);\r\n } else {\r\n await this.openPost(postIdOrIndex, true);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Component } from '@angular/core';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { \r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent\r\n} from '../components/content';\r\nimport { DsMobileHandbookFolderComponent } from '../components/handbook-folder';\r\nimport { UserService } from '../services/user.service';\r\nimport { HandbookItem } from '../components/handbook-detail-modal/ds-mobile-handbook-detail-modal';\r\n\r\n@Component({\r\n selector: 'app-mobile-handbook-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent,\r\n DsMobileHandbookFolderComponent\r\n ],\r\n styles: [`\r\n .folders-grid {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 20px;\r\n justify-items: center;\r\n }\r\n\r\n /* 3 columns at tablet breakpoint (md: 768px) and above\r\n Content area at this breakpoint is ~864px max */\r\n @media (min-width: 768px) {\r\n .folders-grid {\r\n grid-template-columns: repeat(3, 1fr);\r\n }\r\n }\r\n \r\n ds-mobile-handbook-folder {\r\n width: 100%;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Håndbog\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <ds-mobile-content>\r\n <ds-mobile-content-section>\r\n <div class=\"folders-grid\">\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'pink'\"\r\n [iconName]=\"'remixLightbulbLine'\"\r\n [itemCount]=\"8\"\r\n [label]=\"'Forsyninger'\"\r\n [items]=\"utilitiesItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'success'\"\r\n [iconName]=\"'remixKey2Line'\"\r\n [itemCount]=\"4\"\r\n [label]=\"'Sikkerhedsudstyr'\"\r\n [items]=\"sikkerhedsudstyrItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'blue'\"\r\n [iconName]=\"'remixFileList3Line'\"\r\n [itemCount]=\"8\"\r\n [label]=\"'Servicekontrakter'\"\r\n [items]=\"serviceContractsItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder\r\n [variant]=\"'warning'\"\r\n [iconName]=\"'remixToolsLine'\"\r\n [itemCount]=\"5\"\r\n [label]=\"'Udstyr'\"\r\n [items]=\"equipmentItems\">\r\n </ds-mobile-handbook-folder>\r\n </div>\r\n </ds-mobile-content-section>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileHandbookPageComponent {\r\n // Utilities folder data\r\n utilitiesItems: HandbookItem[] = [\r\n {\r\n title: 'El',\r\n description: 'Hovedeltavle placeret i kælderrum B-12. Nødafbryderknap er ved hovedindgangen. Alle kredsløb er mærket.',\r\n contacts: [\r\n { name: 'ElektroTek ApS', initials: 'E', contactPerson: 'Lars Nielsen', phoneNumber: '+45 23 45 67 89' }\r\n ]\r\n },\r\n {\r\n title: 'Elektrisk diagram',\r\n description: 'Komplet diagram over bygningens elektriske installation med alle kredsløb og afbrydere.',\r\n attachments: [\r\n { name: 'Elektrisk_Diagram.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Vandforsyning',\r\n description: 'Hovedvandhane er placeret i kælderens tekniske rum. Individuelle lejlighedsafspærringer er i gangpanelerne. Vandtryk overvåges automatisk.',\r\n contacts: [\r\n { name: 'VVS Hansen', initials: 'V', contactPerson: 'Peter Hansen', phoneNumber: '+45 34 56 78 90' }\r\n ]\r\n },\r\n {\r\n title: 'Varmesystem',\r\n description: 'Fjernvarmetilslutning i kælder. Termostater i hver enhed kan justeres individuelt. Systemet vedligeholdes kvartalsvis af certificerede teknikere.',\r\n contacts: [\r\n { name: 'Varme Service A/S', initials: 'V', contactPerson: 'Maria Jensen', phoneNumber: '+45 45 67 89 01' }\r\n ]\r\n },\r\n {\r\n title: 'Varmeanlæg dokumentation',\r\n description: 'Teknisk dokumentation og vedligeholdelseshistorik for bygningens varmesystem.',\r\n attachments: [\r\n { name: 'Varmeplan.pdf', type: 'pdf' },\r\n { name: 'Vedligeholdelseslog.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Internet & TV',\r\n description: 'Fiberforbindelse i bygningen. Distributionspanel er i stueetageteknisk rum. Hver lejlighed har ethernet-stik i stue og soveværelser.',\r\n contacts: [\r\n { name: 'TeleCom Solutions', initials: 'T', contactPerson: 'Anders Petersen', phoneNumber: '+45 56 78 90 12' }\r\n ]\r\n },\r\n {\r\n title: 'Netværksopsætning guide',\r\n attachments: [\r\n { name: 'Netværksopsætning.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Affaldshåndtering',\r\n description: 'Affaldssorteringsstation placeret i gården. Afhentninger: Dagrenovation (man/tor), Genbrug (ons), Organisk (tir/fre). Storskrald kræver booking.',\r\n attachments: [\r\n { name: 'Affaldsretningslinjer.pdf', type: 'pdf' }\r\n ]\r\n }\r\n ];\r\n\r\n // Safety Equipment folder data\r\n sikkerhedsudstyrItems: HandbookItem[] = [\r\n {\r\n title: 'Fælles områder og sikkerhed',\r\n description: 'Trappeopgange med nødbelysning og brandsikre døre. Postkasser placeret i indgangspartiet. Hold altid flugtveje fri.',\r\n images: [\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/mailboxes.jpg'\r\n ]\r\n },\r\n {\r\n title: 'Hjertestarter (AED)',\r\n description: 'Automatisk hjertestarter placeret i stueetagen ved hovedindgangen. Tilgængelig 24/7. Ingen særlig uddannelse kræves - enheden guider dig gennem processen.',\r\n contacts: [\r\n { name: 'MediTech Service', initials: 'M', contactPerson: 'John Mortensen', phoneNumber: '+45 12 34 56 78' }\r\n ]\r\n },\r\n {\r\n title: 'Brandslukningsudstyr',\r\n description: 'Brandslukkere placeret på hver etage. Eftersyn udføres årligt. Brandalarm aktiveres automatisk ved røg.',\r\n attachments: [\r\n { name: 'Brandplan.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Alarmsystem',\r\n description: 'Adgangskontrol med kodesystem ved alle indgange. Kode ændres kvartalsvis. Ved indbrud kontakt straks politiet og ejendomsadministrationen.',\r\n contacts: [\r\n { name: 'SecureHome A/S', initials: 'S', contactPerson: 'Henrik Johansen', phoneNumber: '+45 98 76 54 32' }\r\n ]\r\n }\r\n ];\r\n\r\n // Service Contracts folder data\r\n serviceContractsItems: HandbookItem[] = [\r\n {\r\n title: 'Rengøringsservice',\r\n description: 'Ugentlig rengøring af fællesarealer inklusiv indgangshal, trapper og elevatorer. Hovedrengøring kvartalsvis. Service leveres mandag-fredag, 6:00-9:00.',\r\n contacts: [\r\n { name: 'CleanCo Denmark', initials: 'C', contactPerson: 'Anne Kristensen', phoneNumber: '+45 89 01 23 45' }\r\n ]\r\n },\r\n {\r\n title: 'Rengøringskontrakt',\r\n attachments: [\r\n { name: 'Rengøringskontrakt_2024.pdf', type: 'pdf' },\r\n { name: 'Rengøringsplan.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Udendørs arealer',\r\n description: 'Fælles grønne områder med bede, siddepladser og terrasse. Beboere må frit benytte området. Respektér planterne og hold området pænt.',\r\n images: [\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/yard.jpg'\r\n ]\r\n },\r\n {\r\n title: 'Havevedligeholdelse',\r\n description: 'Professionel havepleje inklusiv plæneklipning, hækklipning og blomsterbedvedligeholdelse. Vintersnefjerning inkluderet.',\r\n contacts: [\r\n { name: 'Green Gardens ApS', initials: 'G', contactPerson: 'Michael Olsen', phoneNumber: '+45 90 12 34 56' }\r\n ]\r\n },\r\n {\r\n title: 'Haveserviceaftale',\r\n attachments: [\r\n { name: 'Haveserviceaftale.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Vinduespolering',\r\n description: 'Professionel vinduespoleringsservice for alle udvendige vinduer to gange årligt - forår og efterår.',\r\n contacts: [\r\n { name: 'Crystal Clear Windows', initials: 'C', contactPerson: 'Lene Schmidt', phoneNumber: '+45 01 23 45 67' }\r\n ]\r\n },\r\n {\r\n title: 'Sikkerhedsservice',\r\n description: '24/7 overvågningsservice med alarmrespons. Direkte forbindelse til politi og brandvæsen.',\r\n contacts: [\r\n { name: 'SecureHome A/S', initials: 'S', contactPerson: 'Henrik Johansen', phoneNumber: '+45 12 34 56 78' }\r\n ]\r\n },\r\n {\r\n title: 'Sikkerhedskontrakt og procedurer',\r\n attachments: [\r\n { name: 'Sikkerhedskontrakt.pdf', type: 'pdf' },\r\n { name: 'Nødprocedurer.pdf', type: 'pdf' }\r\n ]\r\n }\r\n ];\r\n\r\n // Equipment folder data\r\n equipmentItems: HandbookItem[] = [\r\n {\r\n title: 'Balkon udsigt',\r\n description: 'Eksempel på udsigt fra øverste etagers balkoner. Flere lejligheder har privat altan med fantastisk udsyn.',\r\n images: [\r\n '/Assets/Dummy-photos/balcony-view.jpg'\r\n ]\r\n },\r\n {\r\n title: 'Vaskerum',\r\n description: 'Fælles vaskerum med 4 vaskemaskiner og 4 tørretumblere. Bookingsystem tilgængeligt via beboerportal. Maskiner accepterer betalingskort. Åbningstider: 7:00-22:00.',\r\n contacts: [\r\n { name: 'WashTech Service', initials: 'W', contactPerson: 'Kirsten Berg', phoneNumber: '+45 34 56 78 90' }\r\n ]\r\n },\r\n {\r\n title: 'Vaskeri instruktioner',\r\n attachments: [\r\n { name: 'Vaskeinstruktioner.pdf', type: 'pdf' },\r\n { name: 'Bookingguide.pdf', type: 'pdf' }\r\n ]\r\n },\r\n {\r\n title: 'Vedligeholdelse og reparationer',\r\n description: 'Ved behov for reparationer eller vedligeholdelse i din lejlighed, kontakt vores hausmeister. Akutte problemer håndteres samme dag.',\r\n images: [\r\n '/Assets/Dummy-photos/handyman.jpg'\r\n ],\r\n contacts: [\r\n { name: 'Hausmeister Service', initials: 'H', contactPerson: 'Erik Sørensen', phoneNumber: '+45 56 78 90 12' }\r\n ]\r\n },\r\n {\r\n title: 'Værktøjsudlån',\r\n description: 'Basis håndværktøj tilgængeligt til beboerbrug. Kvittér for værktøj ved receptionen. Returnér inden for 48 timer.',\r\n attachments: [\r\n { name: 'Værktøjsliste.pdf', type: 'pdf' },\r\n { name: 'Udlånspolitik.pdf', type: 'pdf' }\r\n ]\r\n }\r\n ];\r\n \r\n constructor(public userService: UserService) {}\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n}\r\n\r\n","import { Component } from '@angular/core';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { \r\n DsMobileHeaderContentComponent,\r\n DsMobileHeaderContentTileComponent,\r\n TileIconComponent,\r\n TileContentComponent,\r\n TileLabelComponent,\r\n TileValueComponent\r\n} from '../components/header-content';\r\nimport { \r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent\r\n} from '../components/content';\r\nimport { UserService } from '../services/user.service';\r\n\r\n@Component({\r\n selector: 'app-home-page',\r\n standalone: true,\r\n imports: [\r\n DsIconComponent,\r\n DsMobilePageMainComponent,\r\n DsMobileHeaderContentComponent,\r\n DsMobileHeaderContentTileComponent,\r\n TileIconComponent,\r\n TileContentComponent,\r\n TileLabelComponent,\r\n TileValueComponent,\r\n DsMobileContentComponent,\r\n DsMobileContentSectionComponent,\r\n SectionHeaderComponent,\r\n ContentRowComponent\r\n ],\r\n styles: [`\r\n /* Placeholder grey boxes for content */\r\n .grey-box {\r\n height: 120px;\r\n border-radius: 12px;\r\n background: var(--color-background-neutral-tertiary);\r\n flex: 1;\r\n }\r\n\r\n .grey-box.clickable {\r\n background: var(--color-background-brand);\r\n cursor: pointer;\r\n transition: transform var(--transition-duration-fast) var(--ease-smooth);\r\n }\r\n\r\n .grey-box.clickable:active {\r\n transform: scale(0.98);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Hjem\"\r\n headerTitle=\"Velkommen, Lars\"\r\n headerSubtitle=\"Din lejebolig på et øjeblik.\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <!-- Property info tiles in header -->\r\n <ds-mobile-header-content header-content>\r\n <ds-mobile-header-content-tile>\r\n <tile-icon>\r\n <ds-icon name=\"remixHome4Line\" size=\"20px\" color=\"#DFE4FF\" />\r\n </tile-icon>\r\n <tile-content>\r\n <tile-label>Areal</tile-label>\r\n <tile-value>120 m²</tile-value>\r\n </tile-content>\r\n </ds-mobile-header-content-tile>\r\n\r\n <ds-mobile-header-content-tile>\r\n <tile-icon>\r\n <ds-icon name=\"remixCollageLine\" size=\"20px\" color=\"#DFE4FF\" />\r\n </tile-icon>\r\n <tile-content>\r\n <tile-label>Værelser</tile-label>\r\n <tile-value>3 værelser</tile-value>\r\n </tile-content>\r\n </ds-mobile-header-content-tile>\r\n </ds-mobile-header-content>\r\n \r\n <!-- Main page content -->\r\n <ds-mobile-content>\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <!-- Purple box - clickable with brand background -->\r\n <content-row>\r\n <div class=\"grey-box clickable\" (click)=\"navigateToDetail()\"></div>\r\n </content-row>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"half\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"half\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"half\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n\r\n <ds-mobile-content-section>\r\n <section-header width=\"third\"></section-header>\r\n <content-row>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n <div class=\"grey-box\"></div>\r\n </content-row>\r\n </ds-mobile-content-section>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileHomePageComponent {\r\n constructor(\r\n private navCtrl: NavController,\r\n public userService: UserService\r\n ) {\r\n console.log('MobileHomePageComponent constructor');\r\n }\r\n\r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n\r\n navigateToDetail(): void {\r\n // Navigation removed - home/detail page was deleted\r\n console.log('Navigate to detail (page removed)');\r\n }\r\n}\r\n\r\n","import { Animation } from '@ionic/angular';\r\nimport { createAnimation } from '@ionic/core';\r\n\r\n/**\r\n * Custom page transition - iOS-style push/pop\r\n * \r\n * FORWARD (navigating TO detail):\r\n * - Entering page (detail): slides in from RIGHT, z-index 10 (on top)\r\n * - Leaving page (list): slides LEFT slightly, z-index 9 (underneath)\r\n * \r\n * REVERSE (swipe back FROM detail):\r\n * - Entering page (list): slides in from LEFT, z-index 9 (underneath)\r\n * - Leaving page (detail): slides out to RIGHT, z-index 10 (on top)\r\n */\r\nexport const customPageTransition = (_: HTMLElement, opts: any): Animation => {\r\n const DURATION = 400;\r\n const isBackDirection = opts.direction === 'back';\r\n \r\n const rootTransition = createAnimation()\r\n .duration(opts.duration || DURATION)\r\n .easing('cubic-bezier(0.32,0.72,0,1)');\r\n\r\n // Entering page animation\r\n const enteringPage = createAnimation()\r\n .addElement(opts.enteringEl)\r\n .beforeRemoveClass('ion-page-invisible')\r\n .beforeStyles({\r\n 'z-index': isBackDirection ? '9' : '10',\r\n 'opacity': '1'\r\n })\r\n .fromTo('transform', \r\n isBackDirection ? 'translateX(-20%)' : 'translateX(100%)', \r\n 'translateX(0)'\r\n );\r\n\r\n // Leaving page animation\r\n const leavingPage = createAnimation()\r\n .addElement(opts.leavingEl)\r\n .beforeStyles({\r\n 'z-index': isBackDirection ? '10' : '9'\r\n })\r\n .fromTo('transform', \r\n 'translateX(0)', \r\n isBackDirection ? 'translateX(100%)' : 'translateX(-20%)'\r\n );\r\n\r\n rootTransition.addAnimation([enteringPage, leavingPage]);\r\n \r\n return rootTransition;\r\n};\r\n\r\n/**\r\n * Custom back transition - iOS style where page slides out to reveal page underneath\r\n * The entering page (inquiries) slides in from the LEFT underneath\r\n * The leaving page (detail) slides out to the RIGHT on top\r\n */\r\nexport const customBackTransition = (_: HTMLElement, opts: any): Animation => {\r\n const DURATION = 400;\r\n \r\n const rootTransition = createAnimation()\r\n .duration(opts.duration || DURATION)\r\n .easing('cubic-bezier(0.32,0.72,0,1)');\r\n\r\n // Entering page: underneath, sliding in from LEFT (-20% to 0)\r\n const enteringPage = createAnimation()\r\n .addElement(opts.enteringEl)\r\n .beforeRemoveClass('ion-page-invisible')\r\n .beforeStyles({\r\n 'z-index': '9',\r\n 'opacity': '1'\r\n })\r\n .fromTo('transform', 'translateX(-20%)', 'translateX(0)');\r\n\r\n // Leaving page: on top, sliding out to the RIGHT (0 to 100%)\r\n const leavingPage = createAnimation()\r\n .addElement(opts.leavingEl)\r\n .beforeStyles({\r\n 'z-index': '10',\r\n })\r\n .fromTo('transform', 'translateX(0)', 'translateX(100%)');\r\n\r\n rootTransition.addAnimation([enteringPage, leavingPage]);\r\n \r\n return rootTransition;\r\n};\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\nexport interface TabItem {\r\n id: string;\r\n label: string;\r\n badge?: number;\r\n}\r\n\r\n/**\r\n * DsMobileTabBarComponent\r\n * \r\n * Pill-style tab bar for filtering/switching views\r\n * Used in the purple header section of pages\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tab-bar\r\n * [tabs]=\"[\r\n * { id: 'all', label: 'All' },\r\n * { id: 'open', label: 'Open' },\r\n * { id: 'closed', label: 'Closed' }\r\n * ]\"\r\n * [activeTab]=\"'all'\"\r\n * (tabChange)=\"handleTabChange($event)\">\r\n * </ds-mobile-tab-bar>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tab-bar',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n .filter-tabs {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n flex-wrap: wrap;\r\n height: 40px;\r\n }\r\n \r\n .filter-tab {\r\n min-width: 48px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 0px 12px;\r\n height: 32px;\r\n border-radius: 20px;\r\n background: transparent;\r\n border: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n color: rgba(255, 255, 255, 0.6);\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n white-space: nowrap;\r\n }\r\n \r\n .filter-tab.active {\r\n background: var(--color-background-brand, #5d5fef);\r\n color: white;\r\n }\r\n \r\n .filter-tab:hover:not(.active) {\r\n background: rgba(255, 255, 255, 0.1);\r\n }\r\n \r\n .tab-badge {\r\n min-width: 24px;\r\n height: 16px;\r\n padding: 0 6px;\r\n border-radius: 10px;\r\n background: rgba(255, 255, 255, 0.2);\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 600;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n line-height: 1;\r\n }\r\n \r\n .filter-tab.active .tab-badge {\r\n background: rgba(255, 255, 255, 0.3);\r\n color: white;\r\n }\r\n `],\r\n template: `\r\n <div class=\"filter-tabs\">\r\n @for (tab of tabs(); track tab.id) {\r\n <button \r\n class=\"filter-tab\"\r\n [class.active]=\"activeTab() === tab.id\"\r\n (click)=\"handleTabClick(tab.id)\"\r\n [attr.aria-label]=\"tab.label\"\r\n [attr.aria-selected]=\"activeTab() === tab.id\">\r\n {{ tab.label }}\r\n @if (tab.badge && tab.badge > 0) {\r\n <span class=\"tab-badge\">{{ tab.badge }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsMobileTabBarComponent {\r\n /**\r\n * Array of tab items to display\r\n */\r\n tabs = input.required<TabItem[]>();\r\n \r\n /**\r\n * Currently active tab ID\r\n */\r\n activeTab = input.required<string>();\r\n \r\n /**\r\n * Emitted when a tab is clicked\r\n */\r\n tabChange = output<string>();\r\n \r\n handleTabClick(tabId: string): void {\r\n this.tabChange.emit(tabId);\r\n }\r\n}\r\n\r\n","import { Component, signal, computed, effect } from '@angular/core';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileContentComponent } from '../components/content';\r\nimport { DsMobileInteractiveListItemInquiryComponent } from '../components/interactive-list-item-inquiry';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { UserService } from '../services/user.service';\r\nimport { customPageTransition } from '../animations/page-transitions';\r\nimport { DsMobileTabBarComponent, type TabItem } from '../components/tab-bar';\r\n\r\ninterface Inquiry {\r\n id: string;\r\n title: string;\r\n description: string;\r\n status: 'open' | 'closed';\r\n timestamp: string;\r\n category: 'maintenance' | 'plumbing' | 'electrical' | 'heating' | 'security' | 'appliance' | 'other';\r\n}\r\n\r\n@Component({\r\n selector: 'app-mobile-inquiries-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileContentComponent,\r\n DsMobileInteractiveListItemInquiryComponent,\r\n DsIconComponent,\r\n DsMobileTabBarComponent\r\n ],\r\n host: {\r\n class: 'ion-page'\r\n },\r\n styles: [`\r\n .inquiries-container {\r\n display: flex;\r\n flex-direction: column;\r\n max-width: 640px;\r\n }\r\n \r\n .inquiry-list-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Remove custom dividers - now handled by ds-mobile-list-item */\r\n \r\n .empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n color: var(--color-text-primary);\r\n margin: 16px 0 8px 0;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n color: var(--color-text-secondary);\r\n margin: 0;\r\n }\r\n \r\n\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n title=\"Henvendelser\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\">\r\n \r\n <!-- Filter tabs in header -->\r\n <div header-content>\r\n <ds-mobile-tab-bar\r\n [tabs]=\"tabItems\"\r\n [activeTab]=\"filterStatus()\"\r\n (tabChange)=\"setFilter($any($event))\">\r\n </ds-mobile-tab-bar>\r\n </div>\r\n \r\n <ds-mobile-content>\r\n <div class=\"inquiries-container\">\r\n @if (filteredInquiries().length > 0) {\r\n <div class=\"inquiry-list-wrapper\">\r\n @for (inquiry of filteredInquiries(); track inquiry.id; let idx = $index) {\r\n <ds-mobile-interactive-list-item-inquiry\r\n [title]=\"inquiry.title\"\r\n [description]=\"inquiry.description\"\r\n [status]=\"inquiry.status\"\r\n [timestamp]=\"inquiry.timestamp\"\r\n [iconName]=\"getInquiryIcon(inquiry.category)\"\r\n [clickable]=\"true\"\r\n [showChevron]=\"false\"\r\n (inquiryClick)=\"openInquiryDetail(inquiry.id)\"\r\n (longPress)=\"showInquiryActions(inquiry.id)\">\r\n </ds-mobile-interactive-list-item-inquiry>\r\n\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty state -->\r\n <div class=\"empty-state\">\r\n <ds-icon name=\"remixInboxLine\" size=\"48px\" color=\"tertiary\" />\r\n <h3 class=\"empty-state-title\">Ingen henvendelser endnu</h3>\r\n <p class=\"empty-state-description\">\r\n @if (filterStatus() === 'open') {\r\n Du har ingen åbne henvendelser\r\n } @else if (filterStatus() === 'closed') {\r\n Du har ingen lukkede henvendelser\r\n } @else {\r\n Du har ikke oprettet nogen henvendelser endnu\r\n }\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </ds-mobile-content>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileInquiriesPageComponent {\r\n constructor(\r\n public userService: UserService,\r\n private navCtrl: NavController\r\n ) {}\r\n \r\n filterStatus = signal<'all' | 'open' | 'closed'>('all');\r\n \r\n tabItems: TabItem[] = [\r\n { id: 'all', label: 'Alle' },\r\n { id: 'open', label: 'Åben' },\r\n { id: 'closed', label: 'Lukket' }\r\n ];\r\n \r\n inquiries = signal<Inquiry[]>([\r\n {\r\n id: '1',\r\n title: 'Tørretumbler virker ikke',\r\n description: 'I de sidste tre dage har jeg oplevet vedvarende problemer med tørretumbleren. Den starter, men stopper efter få minutter.',\r\n status: 'open',\r\n timestamp: '12 dage siden',\r\n category: 'appliance'\r\n },\r\n {\r\n id: '2',\r\n title: 'Problem med vandtryk',\r\n description: 'Lavt vandtryk i badeværelseshåndvasken. Det er blevet gradvist værre i løbet af den sidste uge.',\r\n status: 'open',\r\n timestamp: '5 dage siden',\r\n category: 'plumbing'\r\n },\r\n {\r\n id: '3',\r\n title: 'Varme virker ikke ordentligt',\r\n description: 'Varmesystemet holder ikke den indstillede temperatur. Lejligheden er meget koldere, end den burde være.',\r\n status: 'closed',\r\n timestamp: '2 måneder siden',\r\n category: 'heating'\r\n }\r\n ]);\r\n \r\n // Computed signals that automatically update when dependencies change\r\n filteredInquiries = computed(() => {\r\n const all = this.inquiries();\r\n const status = this.filterStatus();\r\n \r\n if (status === 'all') {\r\n return all;\r\n } else if (status === 'open') {\r\n return all.filter(i => i.status === 'open');\r\n } else {\r\n return all.filter(i => i.status === 'closed');\r\n }\r\n });\r\n \r\n openInquiries = computed(() => {\r\n return this.inquiries().filter(i => i.status === 'open');\r\n });\r\n \r\n closedInquiries = computed(() => {\r\n return this.inquiries().filter(i => i.status === 'closed');\r\n });\r\n \r\n setFilter(status: 'all' | 'open' | 'closed'): void {\r\n this.filterStatus.set(status);\r\n }\r\n \r\n getInquiryIcon(category: string): string {\r\n return 'remixTodoLine';\r\n }\r\n \r\n openInquiryDetail(inquiryId: string): void {\r\n console.log('Opening inquiry:', inquiryId);\r\n // Navigate to inquiry detail page with custom transition (absolute path outside tabs for animations)\r\n this.navCtrl.navigateForward([`/inquiry-detail/${inquiryId}`], {\r\n animation: customPageTransition\r\n });\r\n }\r\n \r\n showInquiryActions(inquiryId: string): void {\r\n console.log('Showing actions for inquiry:', inquiryId);\r\n // Show bottom sheet with actions (edit, delete, etc.)\r\n }\r\n}\r\n\r\n","import { Component, input, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileListItemStaticComponent\r\n * \r\n * A read-only version of the interactive list item component.\r\n * Used for displaying static information without interaction.\r\n * \r\n * This component has the same structure as the interactive list item but without:\r\n * - Padding\r\n * - Rounded corners\r\n * - Hover states\r\n * - Click interactions\r\n * - Background fill (transparent)\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-list-item-static\r\n * [leadingSize]=\"'40px'\">\r\n * \r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n * \r\n * <div content-main>\r\n * <h3>Main Content</h3>\r\n * <p>Supporting text goes here...</p>\r\n * </div>\r\n * \r\n * <div content-trailing>\r\n * <span>Info</span>\r\n * </div>\r\n * </ds-mobile-list-item-static>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-list-item-static',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[style.--leading-size]': 'leadingSize()'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n background: transparent;\r\n padding: 0;\r\n gap: 12px;\r\n position: relative;\r\n --leading-size: 32px;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -10px;\r\n left: calc(var(--leading-size) + 12px);\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n .content-leading {\r\n flex-shrink: 0;\r\n width: var(--leading-size);\r\n min-height: var(--leading-size);\r\n height: auto;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n min-height: var(--leading-size);\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n align-items: flex-start;\r\n gap: 8px;\r\n }\r\n \r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-start;\r\n }\r\n `],\r\n template: `\r\n @if (hasLeadingContent()) {\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n }\r\n \r\n <div class=\"content-main\">\r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n \r\n @if (hasTrailingContent()) {\r\n <div class=\"content-trailing\">\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n }\r\n `\r\n})\r\nexport class DsMobileListItemStaticComponent {\r\n /**\r\n * CSS size value for the leading content area (e.g., '32px', '40px', '48px')\r\n * Defaults to '32px' for standard list item avatars\r\n */\r\n leadingSize = input<string>('32px');\r\n \r\n /**\r\n * Check if leading content slot has content\r\n */\r\n hasLeadingContent = computed(() => true); // Always render slot container for consistency\r\n \r\n /**\r\n * Check if trailing content slot has content\r\n */\r\n hasTrailingContent = computed(() => true); // Always render slot container for consistency\r\n}\r\n\r\n","import { Component, signal, computed, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NavController, Platform } from '@ionic/angular/standalone';\r\nimport { \r\n IonHeader, \r\n IonToolbar, \r\n IonTitle,\r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent \r\n} from '@ionic/angular/standalone';\r\nimport { DsIconComponent, DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileTabBarComponent, type TabItem } from '../components/tab-bar';\r\nimport { DsMobileListItemStaticComponent } from '../components/list-item-static';\r\nimport { DsMobileInteractiveListItemMessageComponent } from '../components/interactive-list-item-message';\r\nimport { UserService } from '../services/user.service';\r\nimport { MobilePageBase } from '../components/shared/mobile-page-base';\r\nimport { customBackTransition } from '../animations/page-transitions';\r\n\r\ninterface ActivityItem {\r\n id: string;\r\n type: 'assignment' | 'status_change' | 'creation';\r\n actor?: string;\r\n actorInitials?: string;\r\n title: string;\r\n description?: string;\r\n timestamp: string;\r\n date: string;\r\n iconName: string;\r\n iconBgColor?: string;\r\n}\r\n\r\ninterface MessageThread {\r\n id: string;\r\n senderName: string;\r\n senderAvatar: string;\r\n senderInitials: string;\r\n message: string;\r\n role: string;\r\n timestamp: string;\r\n unread: boolean;\r\n}\r\n\r\n@Component({\r\n selector: 'app-mobile-inquiry-detail-page',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsIconComponent,\r\n DsAvatarComponent,\r\n DsMobileTabBarComponent,\r\n DsMobileListItemStaticComponent,\r\n DsMobileInteractiveListItemMessageComponent\r\n ],\r\n host: {\r\n class: 'ion-page'\r\n },\r\n styleUrls: ['./inquiry-detail.example.css'],\r\n template: `\r\n <!-- Fixed header at top -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-detail\">\r\n <!-- Back Button -->\r\n <button class=\"back-button\" (click)=\"goBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftSLine\" size=\"24px\" color=\"white\" />\r\n </button>\r\n \r\n <!-- Title - fades in on scroll -->\r\n <ion-title class=\"header-detail__title\">{{ inquiryTitle }}</ion-title>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content with expandable header -->\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n <!-- Pull to refresh (only on native iOS/Android) -->\r\n @if (isNativePlatform()) {\r\n <ion-refresher \r\n slot=\"fixed\" \r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\" \r\n [pullMin]=\"80\" \r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"remixArrowDownS\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <!-- Expandable header section (purple background) -->\r\n <div class=\"header-expandable\">\r\n <div class=\"header-expandable-inner\">\r\n <div class=\"header-expandable__text\">\r\n <h1 class=\"header-expandable__title\">{{ inquiryTitle }}</h1>\r\n </div>\r\n \r\n <!-- Tabs in header -->\r\n <ds-mobile-tab-bar\r\n [tabs]=\"tabItems\"\r\n [activeTab]=\"activeTab()\"\r\n (tabChange)=\"setActiveTab($event)\">\r\n </ds-mobile-tab-bar>\r\n </div>\r\n </div>\r\n\r\n <!-- Content wrapper -->\r\n <div class=\"content-wrapper\">\r\n <div class=\"content-inner\">\r\n <!-- Activity Tab Content -->\r\n @if (activeTab() === 'activity') {\r\n <div class=\"activity-list\">\r\n @for (activity of activities; track activity.id) {\r\n <div class=\"activity-item\">\r\n @if (activity.actor) {\r\n <!-- Avatar with badge for actor activities -->\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [type]=\"'initials'\"\r\n [initials]=\"activity.actorInitials || ''\"\r\n size=\"md\" />\r\n \r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Icon wrapper for non-actor activities -->\r\n <div class=\"activity-icon-wrapper\">\r\n <ds-icon \r\n [name]=\"activity.iconName\"\r\n size=\"18px\"\r\n color=\"secondary\" />\r\n </div>\r\n }\r\n \r\n <div class=\"activity-content\">\r\n <p class=\"activity-title\">\r\n @if (activity.actor) {\r\n <span class=\"actor-name\">{{ activity.actor }}</span>\r\n <span class=\"activity-text\"> {{ activity.title }}</span>\r\n } @else {\r\n <span class=\"actor-name\">{{ activity.title }}</span>\r\n }\r\n </p>\r\n @if (activity.description) {\r\n <p class=\"activity-description\">{{ activity.description }}</p>\r\n }\r\n <div class=\"activity-timestamp\">\r\n <ds-icon name=\"remixCalendarLine\" size=\"12px\" color=\"--color-text-tertiary\" />\r\n <span>{{ activity.date }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Messages Tab Content -->\r\n @if (activeTab() === 'messages') {\r\n <div class=\"messages-list\">\r\n @for (message of messageThreads; track message.id) {\r\n <ds-mobile-interactive-list-item-message\r\n [senderName]=\"message.senderName\"\r\n [senderRole]=\"message.role\"\r\n [message]=\"message.message\"\r\n [avatarInitials]=\"message.senderInitials\"\r\n [unread]=\"message.unread\"\r\n (messageClick)=\"openMessage(message.id)\">\r\n </ds-mobile-interactive-list-item-message>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Details Tab Content -->\r\n @if (activeTab() === 'details') {\r\n <div class=\"details-list\">\r\n <!-- Assignee -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-avatar\r\n [size]=\"'sm'\"\r\n [type]=\"'initials'\"\r\n [initials]=\"'R'\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-label\">Sagsbehandler</div>\r\n <div class=\"detail-value\">Ricki Meihlen</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Technician -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-avatar\r\n [size]=\"'sm'\"\r\n [type]=\"'initials'\"\r\n [initials]=\"'M'\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-label\">Tekniker</div>\r\n <div class=\"detail-value\">Martin Smith</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Title -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-icon name=\"remixTextBlock\" size=\"20px\" color=\"tertiary\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-value\">{{ inquiryTitle }}</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Description -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-icon name=\"remixAlignLeft\" size=\"20px\" color=\"tertiary\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-value description-text\">\r\n I de sidste tre dage har vi oplevet vedvarende problemer med tørretumbleren i vores lejlighed. På trods af at vi følger betjeningsvejledningen, fejler maskinen konsekvent i at fuldføre sine tørrecyklusser.\r\n </div>\r\n <div class=\"detail-tag\">Husholdningsapparater</div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n \r\n <!-- Photos -->\r\n <ds-mobile-list-item-static [leadingSize]=\"'32px'\">\r\n <div content-leading>\r\n <ds-icon name=\"remixCameraLine\" size=\"20px\" color=\"tertiary\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"photo-grid\">\r\n <button class=\"photo-add\">\r\n <ds-icon name=\"remixAddLine\" size=\"20px\" color=\"tertiary\" />\r\n </button>\r\n <!-- Placeholder photos -->\r\n <div class=\"photo-item\"></div>\r\n <div class=\"photo-item\"></div>\r\n <div class=\"photo-item\"></div>\r\n <div class=\"photo-item\"></div>\r\n </div>\r\n </div>\r\n </ds-mobile-list-item-static>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class MobileInquiryDetailPageComponent extends MobilePageBase implements AfterViewInit {\r\n @ViewChild(IonContent) ionContent?: IonContent;\r\n \r\n // Platform detection\r\n private platform = inject(Platform);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n \r\n inquiryTitle = 'Tørretumbler virker ikke';\r\n activeTab = signal<string>('activity');\r\n \r\n tabItems: TabItem[] = [\r\n { id: 'activity', label: 'Aktivitet' },\r\n { id: 'messages', label: 'Beskeder', badge: 0 },\r\n { id: 'details', label: 'Detaljer' }\r\n ];\r\n \r\n activities: ActivityItem[] = [\r\n {\r\n id: '1',\r\n type: 'assignment',\r\n actor: 'Martin Smith',\r\n actorInitials: 'MS',\r\n title: 'er blevet tildelt som din dedikerede tekniker.',\r\n timestamp: '2 dage siden',\r\n date: '28. feb 2025',\r\n iconName: 'remixUserAddLine'\r\n },\r\n {\r\n id: '2',\r\n type: 'assignment',\r\n actor: 'Ricki Meihlen',\r\n actorInitials: 'RM',\r\n title: 'er blevet tildelt til at håndtere din henvendelse.',\r\n timestamp: '8 dage siden',\r\n date: '22. feb 2025',\r\n iconName: 'remixUserLine'\r\n },\r\n {\r\n id: '3',\r\n type: 'creation',\r\n title: 'Henvendelse oprettet',\r\n timestamp: '8 dage siden',\r\n date: '22. feb 2025',\r\n iconName: 'remixAddCircleLine'\r\n }\r\n ];\r\n \r\n messageThreads: MessageThread[] = [\r\n {\r\n id: '1',\r\n senderName: 'Ove Hindborg',\r\n senderAvatar: '',\r\n senderInitials: 'OH',\r\n message: 'Dejligt at høre! Jeg venter på din teknikerbesøg tidsplan.',\r\n role: 'Sagsbehandler',\r\n timestamp: '2t siden',\r\n unread: true\r\n },\r\n {\r\n id: '2',\r\n senderName: 'Martin Smith',\r\n senderAvatar: '',\r\n senderInitials: 'MS',\r\n message: 'Dejligt at høre! Jeg venter på din teknikerbesøg tidsplan.',\r\n role: 'Tekniker',\r\n timestamp: '4t siden',\r\n unread: true\r\n }\r\n ];\r\n \r\n unreadMessagesCount = computed(() => {\r\n const count = this.messageThreads.filter(m => m.unread).length;\r\n // Update badge in tab items\r\n const messagesTab = this.tabItems.find(t => t.id === 'messages');\r\n if (messagesTab) {\r\n messagesTab.badge = count;\r\n }\r\n return count;\r\n });\r\n \r\n constructor(\r\n public userService: UserService,\r\n private navCtrl: NavController,\r\n private elementRef: ElementRef\r\n ) {\r\n super();\r\n // Trigger initial badge update\r\n this.unreadMessagesCount();\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial setup if needed\r\n }\r\n \r\n setActiveTab(tabId: string): void {\r\n this.activeTab.set(tabId);\r\n }\r\n \r\n goBack(): void {\r\n this.navCtrl.back({ animation: customBackTransition });\r\n }\r\n \r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop;\r\n const threshold = 160;\r\n const fadeDistance = 200;\r\n const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');\r\n const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');\r\n \r\n // Show title in fixed header when scrolled past threshold\r\n if (scrollTop > threshold) {\r\n header?.classList.add('header-scrolled');\r\n } else {\r\n header?.classList.remove('header-scrolled');\r\n }\r\n \r\n // Fade out header-expandable content based on scroll\r\n if (headerExpandable) {\r\n const fadeProgress = Math.min(scrollTop / fadeDistance, 1);\r\n \r\n // Calculate opacity (1 to 0)\r\n const opacity = 1 - fadeProgress;\r\n \r\n // Calculate transform (0px to -20px upward)\r\n const translateY = fadeProgress * -20;\r\n \r\n // Apply styles\r\n headerExpandable.style.opacity = opacity.toString();\r\n headerExpandable.style.transform = `translateY(${translateY}px)`;\r\n }\r\n }\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n openMessage(messageId: string): void {\r\n console.log('Opening message:', messageId);\r\n // Navigate to message thread detail\r\n }\r\n}\r\n\r\n","import { Component, Input, Output, EventEmitter, signal, OnInit, OnDestroy, AfterViewInit, ElementRef, inject, PLATFORM_ID } from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { \r\n IonTabs, \r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconComponent, DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\n/**\r\n * DsMobileTabsComponent\r\n * \r\n * Responsive tab navigation that adapts from mobile to desktop:\r\n * - Mobile (< 768px): Bottom tab bar with icons + labels\r\n * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar\r\n * \r\n * Wraps ion-tabs to maintain native routing functionality while\r\n * providing a responsive navigation experience with branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tabs\r\n * [tabs]=\"tabsConfig\"\r\n * [avatarInitials]=\"'JD'\"\r\n * (avatarClick)=\"handleAvatarClick()\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tabs',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonTabs,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-tabs.css'],\r\n template: `\r\n <ion-tabs>\r\n <ion-tab-bar \r\n [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\" \r\n class=\"ds-tab-bar\"\r\n [class.ds-tab-bar--desktop]=\"isDesktop()\">\r\n \r\n <!-- Logo (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__logo\">\r\n <svg class=\"logomark\" width=\"32\" height=\"28\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n \r\n <!-- Tab buttons container -->\r\n <div class=\"ds-tab-bar__tabs\" *ngIf=\"tabs\">\r\n <ion-tab-button \r\n *ngFor=\"let tab of tabs; trackBy: trackByTabId\"\r\n [tab]=\"tab.id\"\r\n [attr.data-icon]=\"tab.icon\"\r\n [attr.data-icon-active]=\"tab.iconActive\"\r\n [attr.aria-label]=\"tab.label\"\r\n class=\"ds-tab-button ion-activatable\"\r\n [class.tab-selected]=\"isTabActive(tab.id)\">\r\n <div class=\"tab-icon-ripple\"></div>\r\n <div class=\"tab-icon-wrapper\">\r\n <ds-icon \r\n [name]=\"tab.icon\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-inactive\"\r\n />\r\n <ds-icon \r\n [name]=\"tab.iconActive\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-active\"\r\n />\r\n </div>\r\n <ion-label [attr.aria-hidden]=\"true\">{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n </div>\r\n \r\n <!-- Avatar (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__actions\">\r\n <ds-avatar\r\n [initials]=\"avatarInitials\"\r\n [type]=\"avatarType\"\r\n [src]=\"avatarSrc\"\r\n [iconName]=\"avatarIconName\"\r\n (click)=\"handleAvatarClick()\"\r\n style=\"cursor: pointer;\"\r\n />\r\n </div>\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n `\r\n})\r\nexport class DsMobileTabsComponent implements OnInit, OnDestroy, AfterViewInit {\r\n private platformId = inject(PLATFORM_ID);\r\n private resizeListener?: () => void;\r\n private mutationObserver?: MutationObserver;\r\n \r\n // Inputs\r\n @Input() tabs: TabConfig[] = [];\r\n \r\n // Avatar inputs\r\n @Input() avatarType: 'initials' | 'photo' | 'icon' = 'initials';\r\n @Input() avatarInitials: string = 'U';\r\n @Input() avatarSrc: string = '';\r\n @Input() avatarIconName: string = 'remixUser3Line';\r\n \r\n // Outputs\r\n @Output() avatarClick = new EventEmitter<void>();\r\n \r\n // Internal state\r\n activeTab = signal<string>('');\r\n isDesktop = signal<boolean>(false);\r\n \r\n constructor(private elementRef: ElementRef) {}\r\n \r\n ngOnInit(): void {\r\n console.log('DsMobileTabsComponent initialized');\r\n \r\n // Only run breakpoint detection in browser\r\n if (isPlatformBrowser(this.platformId)) {\r\n // Initial check\r\n this.checkBreakpoint();\r\n \r\n // Listen for window resize\r\n this.resizeListener = () => this.checkBreakpoint();\r\n window.addEventListener('resize', this.resizeListener);\r\n }\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial removal\r\n this.removeTitleAttributes();\r\n \r\n // Set up mutation observer to continuously remove title attributes\r\n this.setupTitleRemovalObserver();\r\n }\r\n \r\n ngOnDestroy(): void {\r\n if (isPlatformBrowser(this.platformId) && this.resizeListener) {\r\n window.removeEventListener('resize', this.resizeListener);\r\n }\r\n if (this.mutationObserver) {\r\n this.mutationObserver.disconnect();\r\n }\r\n }\r\n \r\n private setupTitleRemovalObserver(): void {\r\n const config = { \r\n attributes: true, \r\n attributeFilter: ['title'],\r\n subtree: true,\r\n childList: true\r\n };\r\n \r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'attributes' && mutation.attributeName === 'title') {\r\n const target = mutation.target as HTMLElement;\r\n if (target.tagName === 'ION-TAB-BUTTON' && target.hasAttribute('title')) {\r\n target.removeAttribute('title');\r\n }\r\n }\r\n });\r\n // Also do a sweep after any changes\r\n this.removeTitleAttributes();\r\n });\r\n \r\n this.mutationObserver.observe(this.elementRef.nativeElement, config);\r\n }\r\n \r\n private removeTitleAttributes(): void {\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n tabButtons.forEach((button: HTMLElement) => {\r\n if (button.hasAttribute('title')) {\r\n button.removeAttribute('title');\r\n }\r\n // Also remove from the native button inside shadow DOM\r\n const nativeButton = button.shadowRoot?.querySelector('button');\r\n if (nativeButton?.hasAttribute('title')) {\r\n nativeButton.removeAttribute('title');\r\n }\r\n });\r\n }\r\n \r\n private checkBreakpoint(): void {\r\n // 768px matches the @media (min-width: 768px) in CSS\r\n this.isDesktop.set(window.innerWidth >= 768);\r\n }\r\n \r\n trackByTabId(index: number, tab: TabConfig): string {\r\n return tab.id;\r\n }\r\n \r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n \r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, OnInit } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { UserService } from '../services/user.service';\r\nimport { DsMobileTabsComponent, TabConfig } from '../components/ds-mobile-tabs';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileActionsBottomSheetComponent, ActionResult } from '../components/bottom-sheet';\r\n\r\n@Component({\r\n selector: 'app-mobile-tabs-example',\r\n standalone: true,\r\n imports: [DsMobileTabsComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n height: 100vh;\r\n width: 100vw;\r\n position: relative;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-tabs\r\n [tabs]=\"tabs\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n (avatarClick)=\"handleAvatarClick()\"\r\n />\r\n `\r\n})\r\nexport class MobileTabsExampleComponent implements OnInit {\r\n constructor(\r\n public userService: UserService,\r\n private modalController: ModalController,\r\n private router: Router\r\n ) {\r\n console.log('MobileTabsExampleComponent constructor');\r\n }\r\n \r\n ngOnInit() {\r\n console.log('MobileTabsExampleComponent ngOnInit');\r\n // Configure user avatar globally - this is now the single source of truth\r\n this.userService.setAvatarInitials('LM');\r\n this.userService.setAvatarType('initials');\r\n }\r\n \r\n tabs: TabConfig[] = [\r\n {\r\n id: 'home',\r\n label: 'Hjem',\r\n route: 'home',\r\n icon: 'remixHomeSmile2Line',\r\n iconActive: 'remixHomeSmile2Fill'\r\n },\r\n {\r\n id: 'inquiries',\r\n label: 'Henvendelser',\r\n route: 'inquiries',\r\n icon: 'remixFileList3Line',\r\n iconActive: 'remixFileList3Fill'\r\n },\r\n {\r\n id: 'announcements',\r\n label: 'Fællesskab',\r\n route: 'announcements',\r\n icon: 'remixCommunityLine',\r\n iconActive: 'remixCommunityFill'\r\n },\r\n {\r\n id: 'handbook',\r\n label: 'Håndbog',\r\n route: 'handbook',\r\n icon: 'remixBook2Line',\r\n iconActive: 'remixBook2Fill'\r\n }\r\n ];\r\n \r\n async handleAvatarClick(): Promise<void> {\r\n console.log('Avatar clicked - opening profile bottom sheet');\r\n \r\n const sheet = await this.modalController.create({\r\n component: DsMobileActionsBottomSheetComponent,\r\n componentProps: {\r\n customActionGroups: [\r\n {\r\n actions: [\r\n {\r\n action: 'profile',\r\n title: 'Min profil',\r\n icon: 'remixUser3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'settings',\r\n title: 'Indstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'whitelabel-demo',\r\n title: 'Whitelabel Demo',\r\n icon: 'remixPaletteLine',\r\n destructive: false\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'logout',\r\n title: 'Log ud',\r\n icon: 'remixLogoutBoxLine',\r\n destructive: true\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n // Auto-height: no breakpoints, no handle\r\n cssClass: 'ds-bottom-sheet auto-height'\r\n });\r\n \r\n await sheet.present();\r\n \r\n const result = await sheet.onWillDismiss<ActionResult>();\r\n if (result.data?.action) {\r\n console.log('Profile action selected:', result.data.action);\r\n \r\n switch (result.data.action) {\r\n case 'logout':\r\n console.log('Logging out...');\r\n // TODO: Implement logout logic\r\n break;\r\n case 'profile':\r\n console.log('Opening profile...');\r\n // TODO: Navigate to profile page\r\n break;\r\n case 'settings':\r\n console.log('Opening settings...');\r\n // TODO: Navigate to settings page\r\n break;\r\n case 'whitelabel-demo':\r\n console.log('Opening whitelabel demo...');\r\n this.router.navigate(['/whitelabel-demo']);\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n","import { Component, signal, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\r\nimport { Router, ActivatedRoute } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport {\r\n DsAvatarComponent,\r\n DsIconComponent,\r\n DsButtonComponent\r\n} from '@propbinder/design-system';\r\nimport { DsMobilePageDetailsComponent } from '../components/page-details';\r\nimport { UserService } from '../services/user.service';\r\n\r\n/**\r\n * PostCreatePageComponent\r\n * \r\n * Full-screen detail page for creating new posts in the community feed.\r\n * Features Threads-inspired interface with rich text editing capabilities.\r\n */\r\n@Component({\r\n selector: 'app-post-create-page',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsAvatarComponent,\r\n DsIconComponent,\r\n DsButtonComponent,\r\n DsMobilePageDetailsComponent\r\n ],\r\n styles: [`\r\n .post-create-container {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n max-width: 640px;\r\n }\r\n \r\n /* ============================================\r\n CONTENT AREA\r\n ============================================ */\r\n \r\n .content {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n }\r\n \r\n .post-composer {\r\n display: flex;\r\n gap: 12px;\r\n margin-bottom: 24px;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-composer__avatar {\r\n flex-shrink: 0;\r\n padding-top: 2px;\r\n }\r\n \r\n .post-composer__main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .post-composer__header {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 32px;\r\n }\r\n \r\n .post-composer__username {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 15px;\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .post-composer__textarea {\r\n width: 100%;\r\n min-height: 120px;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 15px;\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n background: transparent;\r\n padding: 0;\r\n }\r\n \r\n .post-composer__textarea::placeholder {\r\n color: var(--color-text-tertiary, #999999);\r\n }\r\n \r\n .post-composer__actions {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 16px;\r\n }\r\n \r\n .post-composer__action-btns {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n \r\n .post-composer__action-btn {\r\n background: none;\r\n border: none;\r\n padding: 0;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-text-secondary, #737373);\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .post-composer__action-btn:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n /* Thread connector line */\r\n .thread-line {\r\n position: absolute;\r\n left: 35px;\r\n top: 60px;\r\n bottom: 0;\r\n width: 2px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n /* ============================================\r\n MOBILE OPTIMIZATIONS\r\n ============================================ */\r\n \r\n @media (max-width: 768px) {\r\n .content {\r\n padding: 12px 16px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-details\r\n [title]=\"pageTitle()\"\r\n [backRoute]=\"'/mobile-tabs-example/announcements'\"\r\n (back)=\"handleCancel()\">\r\n \r\n <div class=\"post-create-container\">\r\n <div class=\"post-composer\">\r\n <div class=\"post-composer__avatar\">\r\n <ds-avatar \r\n [initials]=\"userService.avatarInitials()\"\r\n [type]=\"userService.avatarType()\"\r\n [src]=\"userService.avatarSrc()\"\r\n size=\"md\" />\r\n </div>\r\n \r\n <div class=\"post-composer__main\">\r\n <div class=\"post-composer__header\">\r\n <span class=\"post-composer__username\">{{ username() }}</span>\r\n </div>\r\n \r\n <textarea\r\n #textareaInput\r\n class=\"post-composer__textarea\"\r\n [(ngModel)]=\"postContent\"\r\n [placeholder]=\"placeholder()\"\r\n (input)=\"handleInput()\">\r\n </textarea>\r\n \r\n <div class=\"post-composer__actions\">\r\n <div class=\"post-composer__action-btns\">\r\n <button class=\"post-composer__action-btn\" (click)=\"handleAddImage()\">\r\n <ds-icon name=\"remixImageLine\" size=\"22px\" />\r\n </button>\r\n <button class=\"post-composer__action-btn\" (click)=\"handleAddEmoji()\">\r\n <ds-icon name=\"remixEmotionLine\" size=\"22px\" />\r\n </button>\r\n </div>\r\n \r\n <ds-button\r\n variant=\"primary\"\r\n size=\"md\"\r\n [disabled]=\"!canPost()\"\r\n (clicked)=\"handlePost()\">\r\n {{ submitButtonLabel() }}\r\n </ds-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-page-details>\r\n `\r\n})\r\nexport class PostCreatePageComponent implements AfterViewInit, OnInit {\r\n @ViewChild('textareaInput') textareaInput?: ElementRef<HTMLTextAreaElement>;\r\n \r\n postContent = '';\r\n username = signal('Lars Mikkelsen');\r\n placeholder = signal(\"What's new?\");\r\n \r\n // Edit mode state\r\n isEditMode = signal(false);\r\n postId = signal<string | null>(null);\r\n pageTitle = signal('New post');\r\n submitButtonLabel = signal('Post');\r\n \r\n constructor(\r\n private router: Router,\r\n private route: ActivatedRoute,\r\n public userService: UserService\r\n ) {}\r\n \r\n ngOnInit(): void {\r\n // Check for edit mode via query parameters\r\n this.route.queryParams.subscribe(params => {\r\n const editMode = params['edit'] === 'true';\r\n const postId = params['id'];\r\n const content = params['content'];\r\n \r\n if (editMode && postId) {\r\n this.isEditMode.set(true);\r\n this.postId.set(postId);\r\n this.pageTitle.set('Edit post');\r\n this.submitButtonLabel.set('Save');\r\n \r\n // Prefill content if provided\r\n if (content) {\r\n this.postContent = decodeURIComponent(content);\r\n }\r\n } else {\r\n // Reset to create mode\r\n this.isEditMode.set(false);\r\n this.postId.set(null);\r\n this.pageTitle.set('New post');\r\n this.submitButtonLabel.set('Post');\r\n this.postContent = '';\r\n }\r\n });\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Focus the textarea after view initialization to trigger keyboard on mobile\r\n setTimeout(() => {\r\n this.textareaInput?.nativeElement.focus();\r\n }, 300);\r\n }\r\n \r\n handleInput(): void {\r\n // Handle text input changes\r\n }\r\n \r\n canPost(): boolean {\r\n return this.postContent.trim().length > 0;\r\n }\r\n \r\n handleCancel(): void {\r\n if (this.postContent.trim().length > 0) {\r\n // Show confirmation dialog\r\n const confirmed = confirm('Discard this post?');\r\n if (confirmed) {\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n } else {\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n }\r\n \r\n handlePost(): void {\r\n if (!this.canPost()) return;\r\n \r\n if (this.isEditMode()) {\r\n console.log('Updating post:', this.postId(), this.postContent);\r\n // TODO: Implement post update logic\r\n // this.postService.updatePost(this.postId(), this.postContent).subscribe(() => {\r\n // this.router.navigate(['/mobile-tabs-example/community']);\r\n // });\r\n } else {\r\n console.log('Creating post:', this.postContent);\r\n // TODO: Implement post creation logic\r\n // this.postService.createPost(this.postContent).subscribe(() => {\r\n // this.router.navigate(['/mobile-tabs-example/community']);\r\n // });\r\n }\r\n \r\n // For now, just navigate back\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n \r\n handleAddImage(): void {\r\n console.log('Add image');\r\n // TODO: Open image picker\r\n }\r\n \r\n handleAddEmoji(): void {\r\n console.log('Add emoji');\r\n // TODO: Open emoji picker\r\n }\r\n}\r\n\r\n","import { Component } from '@angular/core';\r\nimport { DsMobilePageDetailsComponent } from '../components/page-details';\r\nimport { \r\n DsMobilePostCardComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../components/post-card';\r\nimport { DsMobileCommentComponent } from '../components/comment';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../components/lightbox';\r\nimport { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';\r\nimport { DsMobileCommentActionsBottomSheetComponent, CommentActionResult } from '../components/bottom-sheet';\r\n\r\n@Component({\r\n selector: 'app-mobile-post-detail-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageDetailsComponent,\r\n DsMobilePostCardComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCommentComponent\r\n ],\r\n styles: [`\r\n .post-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n max-width: 640px;\r\n }\r\n \r\n .post-section {\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding-bottom: 16px;\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n .comments-section {\r\n display: flex;\r\n flex-direction: column;\r\n /* Negative margin to pull comments out by 8px on each side */\r\n /* Page has 20px padding, this makes comments effectively 12px from edge */\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n .comments-header {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 18px;\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin-bottom: 16px;\r\n /* Add padding to keep header at 20px from edge (8px to offset negative margin) */\r\n padding-left: 8px;\r\n padding-right: 8px;\r\n }\r\n \r\n .comments-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-details title=\"Opslag\">\r\n <div class=\"post-detail-container\">\r\n <!-- Post Section -->\r\n <div class=\"post-section\">\r\n <ds-mobile-post-card\r\n [authorName]=\"'Sophie Andersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'4t siden'\"\r\n [avatarInitials]=\"'SA'\"\r\n [variant]=\"'detail'\">\r\n \r\n <post-content class=\"no-indent\">\r\n <post-text>Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️</post-text>\r\n <post-media>\r\n <img \r\n src=\"/Assets/Dummy-photos/balcony-view.jpg\" \r\n alt=\"Altanudsigt\" \r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox('/Assets/Dummy-photos/balcony-view.jpg', 'Altanudsigt', 'Morgenkaffe har aldrig smagt så godt ☕️')\"\r\n />\r\n </post-media>\r\n </post-content>\r\n \r\n <post-actions class=\"no-indent\">\r\n <action-like [active]=\"true\" [count]=\"156\" />\r\n <action-comment [count]=\"34\" />\r\n </post-actions>\r\n </ds-mobile-post-card>\r\n </div>\r\n \r\n <!-- Comments Section -->\r\n <div class=\"comments-section\">\r\n <h2 class=\"comments-header\">{{ repliesCount }} svar</h2>\r\n \r\n <div class=\"comments-list\">\r\n <ds-mobile-comment\r\n [authorName]=\"'Anders Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3t siden'\"\r\n [avatarInitials]=\"'AJ'\"\r\n [content]=\"'Wow, den udsigt er fantastisk! Hvilken etage er du på?'\"\r\n [likeCount]=\"12\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Anders Jensen', 'Wow, den udsigt er fantastisk! Hvilken etage er du på?', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Thomas Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3t siden'\"\r\n [avatarInitials]=\"'TH'\"\r\n [content]=\"'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆'\"\r\n [isLiked]=\"true\"\r\n [likeCount]=\"8\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"true\"\r\n (longPress)=\"handleCommentLongPress('Thomas Hansen', 'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆', true)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Emma Petersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarInitials]=\"'EP'\"\r\n [content]=\"'Dette er præcis derfor jeg elsker at bo her. Godt billede!'\"\r\n [likeCount]=\"15\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Emma Petersen', 'Dette er præcis derfor jeg elsker at bo her. Godt billede!', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Nikolaj Sørensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarInitials]=\"'NS'\"\r\n [content]=\"'Solnedgangene fra den vinkel må være utrolige'\"\r\n [likeCount]=\"6\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Nikolaj Sørensen', 'Solnedgangene fra den vinkel må være utrolige', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Mette Larsen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1t siden'\"\r\n [avatarInitials]=\"'ML'\"\r\n [content]=\"'Giver mig lyst til at få min morgenkaffe på altanen også! ☕'\"\r\n [likeCount]=\"9\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Mette Larsen', 'Giver mig lyst til at få min morgenkaffe på altanen også! ☕', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Frederik Nielsen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1t siden'\"\r\n [avatarInitials]=\"'FN'\"\r\n [content]=\"'Heldig! Min altan vender den anden vej, men stadig pæn'\"\r\n [likeCount]=\"4\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Frederik Nielsen', 'Heldig! Min altan vender den anden vej, men stadig pæn', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Caroline Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'45m siden'\"\r\n [avatarInitials]=\"'CJ'\"\r\n [content]=\"'Denne bygning har den bedste udsigt i byen, uden tvivl'\"\r\n [likeCount]=\"11\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Caroline Jensen', 'Denne bygning har den bedste udsigt i byen, uden tvivl', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Anna Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'30m siden'\"\r\n [avatarInitials]=\"'AH'\"\r\n [content]=\"'Jeg skal se din altan en dag! 😍'\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Anna Hansen', 'Jeg skal se din altan en dag! 😍', false)\" />\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-page-details>\r\n `\r\n})\r\nexport class MobilePostDetailPageComponent {\r\n repliesCount = 6;\r\n \r\n constructor(\r\n private lightbox: DsMobileLightboxService,\r\n private bottomSheet: DsMobileBottomSheetService\r\n ) {}\r\n \r\n /**\r\n * Open an image in the lightbox viewer\r\n */\r\n openImageLightbox(imageSrc: string, title: string, description: string): void {\r\n const authorMeta: LightboxAuthor = {\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n timestamp: '4t siden'\r\n };\r\n \r\n this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: imageSrc,\r\n alt: title,\r\n title: title,\r\n description: description,\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false, // Single image, no need for controls\r\n showInfo: true\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a comment to show action sheet\r\n */\r\n async handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobileCommentActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnComment\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as CommentActionResult).action;\r\n \r\n switch (action) {\r\n case 'like':\r\n console.log('Like comment by', authorName);\r\n // Implement like logic\r\n break;\r\n case 'reply':\r\n console.log('Reply to comment by', authorName);\r\n // Implement reply logic\r\n break;\r\n case 'edit':\r\n console.log('Edit comment by', authorName);\r\n // Implement edit logic\r\n break;\r\n case 'delete':\r\n console.log('Delete comment by', authorName);\r\n // Implement delete logic (with confirmation)\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable, signal, effect } from '@angular/core';\r\n\r\nexport interface WhitelabelConfig {\r\n // Logo assets\r\n logoUrl: string; // Full logo for header (typically horizontal)\r\n logoMarkUrl: string; // Compact logo mark for avatars/badges\r\n logoAlt: string; // Alt text for accessibility\r\n \r\n // Logo dimensions (optional, for optimization)\r\n logoWidth?: number;\r\n logoHeight?: number;\r\n logoMarkWidth?: number;\r\n logoMarkHeight?: number;\r\n \r\n // Brand colors - these will update CSS custom properties\r\n primaryColor: string; // Maps to --color-background-brand\r\n secondaryColor: string; // Maps to --color-brand-secondary\r\n \r\n // Organization info\r\n organizationName: string;\r\n organizationId: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: WhitelabelConfig = {\r\n logoUrl: '/assets/logos/propbinder-logo.svg',\r\n logoMarkUrl: '/assets/logos/propbinder-logomark.svg',\r\n logoAlt: 'Propbinder',\r\n primaryColor: '#6B5FF5', // Propbinder brand purple (--color-background-brand)\r\n secondaryColor: '#221a4c', // Propbinder dark purple for headers (--color-brand-secondary)\r\n organizationName: 'Propbinder',\r\n organizationId: 'default'\r\n};\r\n\r\n/**\r\n * WhitelabelService\r\n * \r\n * Manages whitelabel configuration including logos and brand colors.\r\n * Automatically updates CSS custom properties when colors change.\r\n * \r\n * @example\r\n * Initialize with custom config:\r\n * ```typescript\r\n * whitelabelService.initialize({\r\n * logoUrl: '/assets/logos/acme-logo.svg',\r\n * logoMarkUrl: '/assets/logos/acme-mark.svg',\r\n * primaryColor: '#2563eb',\r\n * secondaryColor: '#3b82f6',\r\n * organizationName: 'Acme Corp'\r\n * });\r\n * ```\r\n * \r\n * Load from API:\r\n * ```typescript\r\n * await whitelabelService.loadFromApi('acme-corp');\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class WhitelabelService {\r\n private _config = signal<WhitelabelConfig>(DEFAULT_CONFIG);\r\n \r\n // Readonly getters for accessing config values\r\n readonly logoUrl = () => this._config().logoUrl;\r\n readonly logoMarkUrl = () => this._config().logoMarkUrl;\r\n readonly logoAlt = () => this._config().logoAlt;\r\n readonly primaryColor = () => this._config().primaryColor;\r\n readonly secondaryColor = () => this._config().secondaryColor;\r\n readonly organizationName = () => this._config().organizationName;\r\n readonly organizationId = () => this._config().organizationId;\r\n \r\n // Full config accessor\r\n readonly config = this._config.asReadonly();\r\n \r\n constructor() {\r\n // Apply default colors on initialization\r\n this.applyColors(DEFAULT_CONFIG.primaryColor, DEFAULT_CONFIG.secondaryColor);\r\n \r\n // Watch for config changes and update CSS custom properties\r\n effect(() => {\r\n const config = this._config();\r\n this.applyColors(config.primaryColor, config.secondaryColor);\r\n });\r\n }\r\n \r\n /**\r\n * Initialize whitelabel configuration\r\n * Call this early in app initialization (app.config.ts or app.component.ts)\r\n */\r\n initialize(config: Partial<WhitelabelConfig>) {\r\n this._config.update(current => ({\r\n ...current,\r\n ...config\r\n }));\r\n }\r\n \r\n /**\r\n * Load whitelabel config from API\r\n * Typically called on app startup based on subdomain, user tenant, etc.\r\n * \r\n * @param organizationId - The organization identifier (subdomain, tenant ID, etc.)\r\n */\r\n async loadFromApi(organizationId?: string): Promise<void> {\r\n try {\r\n // Example API call structure\r\n // const response = await fetch(`/api/whitelabel/${organizationId || 'default'}`);\r\n // const config = await response.json();\r\n // this.initialize(config);\r\n \r\n console.log('Loading whitelabel config from API for:', organizationId);\r\n \r\n // Example: Different configs for different organizations\r\n if (organizationId === 'demo-client') {\r\n this.initialize({\r\n logoUrl: '/assets/logos/demo-logo.svg',\r\n logoMarkUrl: '/assets/logos/demo-mark.svg',\r\n logoAlt: 'Demo Client',\r\n primaryColor: '#2563eb', // Blue\r\n secondaryColor: '#3b82f6', // Lighter blue\r\n organizationName: 'Demo Client',\r\n organizationId: 'demo-client'\r\n });\r\n }\r\n // Add more organization-specific configs as needed\r\n \r\n } catch (error) {\r\n console.error('Failed to load whitelabel config:', error);\r\n // Fallback to defaults already set\r\n }\r\n }\r\n \r\n /**\r\n * Update config dynamically (e.g., when user switches organizations)\r\n */\r\n updateConfig(updates: Partial<WhitelabelConfig>) {\r\n this.initialize(updates);\r\n }\r\n \r\n /**\r\n * Update only the brand colors\r\n */\r\n updateColors(primaryColor: string, secondaryColor: string) {\r\n this._config.update(current => ({\r\n ...current,\r\n primaryColor,\r\n secondaryColor\r\n }));\r\n }\r\n \r\n /**\r\n * Reset to default configuration\r\n */\r\n resetToDefault() {\r\n this._config.set(DEFAULT_CONFIG);\r\n }\r\n \r\n /**\r\n * Apply colors to CSS custom properties\r\n * This updates the actual CSS variables used throughout the app\r\n */\r\n private applyColors(primaryColor: string, secondaryColor: string) {\r\n if (typeof document !== 'undefined') {\r\n const root = document.documentElement;\r\n root.style.setProperty('--color-background-brand', primaryColor);\r\n root.style.setProperty('--color-brand-secondary', secondaryColor);\r\n \r\n console.log('Applied whitelabel colors:', { primaryColor, secondaryColor });\r\n }\r\n }\r\n}\r\n\r\n","import { Component, Input, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { WhitelabelService } from '../../services/whitelabel.service';\r\n\r\nexport type LogoVariant = 'full' | 'mark';\r\nexport type LogoSize = 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * DsLogoComponent\r\n * \r\n * Displays the whitelabeled logo or logomark based on current configuration.\r\n * Automatically pulls logo assets from WhitelabelService.\r\n * \r\n * @example\r\n * Full logo in header:\r\n * ```html\r\n * <ds-logo variant=\"full\" size=\"md\" />\r\n * ```\r\n * \r\n * Logomark for compact spaces:\r\n * ```html\r\n * <ds-logo variant=\"mark\" size=\"sm\" />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-logo',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n line-height: 0;\r\n }\r\n \r\n .logo {\r\n display: block;\r\n object-fit: contain;\r\n }\r\n \r\n /* Size variants for full logo */\r\n .logo--full.logo--sm { height: 24px; width: auto; }\r\n .logo--full.logo--md { height: 32px; width: auto; }\r\n .logo--full.logo--lg { height: 40px; width: auto; }\r\n .logo--full.logo--xl { height: 48px; width: auto; }\r\n \r\n /* Size variants for logomark */\r\n .logo--mark.logo--sm { height: 20px; width: 20px; }\r\n .logo--mark.logo--md { height: 28px; width: 28px; }\r\n .logo--mark.logo--lg { height: 36px; width: 36px; }\r\n .logo--mark.logo--xl { height: 44px; width: 44px; }\r\n `],\r\n template: `\r\n <img \r\n [src]=\"logoSrc()\"\r\n [alt]=\"logoAlt()\"\r\n [class]=\"logoClasses()\"\r\n [style.height.px]=\"customHeight\"\r\n [style.width.px]=\"customWidth\"\r\n />\r\n `\r\n})\r\nexport class DsLogoComponent {\r\n private whitelabelService = inject(WhitelabelService);\r\n \r\n @Input() variant: LogoVariant = 'full';\r\n @Input() size: LogoSize = 'md';\r\n @Input() customHeight?: number;\r\n @Input() customWidth?: number;\r\n \r\n logoSrc = computed(() => {\r\n return this.variant === 'full' \r\n ? this.whitelabelService.logoUrl()\r\n : this.whitelabelService.logoMarkUrl();\r\n });\r\n \r\n logoAlt = computed(() => {\r\n const alt = this.whitelabelService.logoAlt();\r\n return this.variant === 'full' ? alt : `${alt} logo`;\r\n });\r\n \r\n logoClasses = computed(() => {\r\n return `logo logo--${this.variant} logo--${this.size}`;\r\n });\r\n}\r\n\r\n","import { Component, Input, computed, ViewEncapsulation } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsLogoComponent } from '../logo/ds-logo';\r\n\r\nexport type AvatarType = 'initials' | 'photo' | 'icon';\r\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\nexport type BadgePosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';\r\n\r\n/**\r\n * DsAvatarWithBadgeComponent\r\n * \r\n * Displays an avatar with a logomark badge overlay.\r\n * Useful for showing user avatars with organization branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-avatar-with-badge\r\n * [type]=\"'initials'\"\r\n * [initials]=\"'JD'\"\r\n * [size]=\"'lg'\"\r\n * [badgePosition]=\"'bottom-right'\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-avatar-with-badge',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsLogoComponent],\r\n encapsulation: ViewEncapsulation.Emulated,\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n position: relative;\r\n }\r\n \r\n .avatar-badge-container {\r\n position: relative;\r\n display: inline-block;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n background: white;\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\r\n }\r\n \r\n /* Badge positioning */\r\n .avatar-badge--bottom-right {\r\n bottom: 0;\r\n right: 0;\r\n }\r\n \r\n .avatar-badge--bottom-left {\r\n bottom: 0;\r\n left: 0;\r\n }\r\n \r\n .avatar-badge--top-right {\r\n top: 0;\r\n right: 0;\r\n }\r\n \r\n .avatar-badge--top-left {\r\n top: 0;\r\n left: 0;\r\n }\r\n \r\n /* Badge sizes based on avatar size */\r\n .avatar-badge--xs { width: 16px; height: 16px; padding: 3px; }\r\n .avatar-badge--sm { width: 20px; height: 20px; padding: 3px; }\r\n .avatar-badge--md { width: 24px; height: 24px; padding: 4px; }\r\n .avatar-badge--lg { width: 32px; height: 32px; padding: 5px; }\r\n .avatar-badge--xl { width: 40px; height: 40px; padding: 6px; }\r\n `],\r\n template: `\r\n <div class=\"avatar-badge-container\">\r\n <ds-avatar\r\n [type]=\"type\"\r\n [size]=\"size\"\r\n [initials]=\"initials\"\r\n [src]=\"src\"\r\n [iconName]=\"iconName\"\r\n />\r\n \r\n @if (showBadge) {\r\n <div [class]=\"badgeClasses()\">\r\n <ds-logo \r\n variant=\"mark\" \r\n [customHeight]=\"badgeLogoSize()\"\r\n [customWidth]=\"badgeLogoSize()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsAvatarWithBadgeComponent {\r\n // Avatar props\r\n @Input() type: AvatarType = 'initials';\r\n @Input() size: AvatarSize = 'md';\r\n @Input() initials: string = '';\r\n @Input() src: string = '';\r\n @Input() iconName: string = 'remixUser3Fill';\r\n \r\n // Badge props\r\n @Input() showBadge: boolean = true;\r\n @Input() badgePosition: BadgePosition = 'bottom-right';\r\n \r\n badgeClasses = computed(() => {\r\n return `avatar-badge avatar-badge--${this.badgePosition} avatar-badge--${this.size}`;\r\n });\r\n \r\n // Calculate badge logo size based on avatar size\r\n badgeLogoSize = computed(() => {\r\n const sizeMap: Record<AvatarSize, number> = {\r\n xs: 10,\r\n sm: 14,\r\n md: 16,\r\n lg: 22,\r\n xl: 28\r\n };\r\n return sizeMap[this.size];\r\n });\r\n}\r\n\r\n","import { Component, OnInit, inject, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { WhitelabelService } from '../services/whitelabel.service';\r\nimport { DsLogoComponent } from '../components/logo/ds-logo';\r\nimport { DsAvatarWithBadgeComponent } from '../components/avatar-with-badge/ds-avatar-with-badge';\r\nimport { IonContent, IonHeader, IonToolbar, IonTitle, IonButton } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Whitelabel Demo Page\r\n * \r\n * Demonstrates the whitelabeling system with live color and logo switching.\r\n */\r\n@Component({\r\n selector: 'app-whitelabel-demo',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonButton,\r\n DsLogoComponent,\r\n DsAvatarWithBadgeComponent\r\n ],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n ion-toolbar {\r\n --background: var(--color-brand-secondary);\r\n --color: white;\r\n }\r\n \r\n ion-content {\r\n --background: #f5f5f5;\r\n }\r\n \r\n .demo-container {\r\n padding: 20px;\r\n max-width: 800px;\r\n margin: 0 auto;\r\n }\r\n \r\n .demo-section {\r\n margin-bottom: 32px;\r\n }\r\n \r\n .demo-section h2 {\r\n margin-bottom: 16px;\r\n font-size: 20px;\r\n font-weight: 600;\r\n }\r\n \r\n .logo-showcase {\r\n display: flex;\r\n gap: 24px;\r\n align-items: center;\r\n padding: 24px;\r\n background: white;\r\n border-radius: 8px;\r\n }\r\n \r\n .avatar-showcase {\r\n display: flex;\r\n gap: 16px;\r\n align-items: center;\r\n padding: 24px;\r\n background: white;\r\n border-radius: 8px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n .button-group {\r\n display: flex;\r\n gap: 12px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n .color-demo {\r\n padding: 24px;\r\n background: white;\r\n border-radius: 8px;\r\n }\r\n \r\n .color-swatch {\r\n display: flex;\r\n gap: 16px;\r\n margin-top: 16px;\r\n }\r\n \r\n .swatch {\r\n flex: 1;\r\n min-height: 100px;\r\n border-radius: 8px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: white;\r\n font-weight: 600;\r\n }\r\n \r\n .swatch--primary {\r\n background: var(--color-background-brand);\r\n }\r\n \r\n .swatch--secondary {\r\n background: var(--color-brand-secondary);\r\n }\r\n \r\n .current-config {\r\n padding: 16px;\r\n background: #f5f5f5;\r\n border-radius: 8px;\r\n margin-top: 16px;\r\n }\r\n \r\n .current-config pre {\r\n margin: 0;\r\n font-size: 12px;\r\n overflow-x: auto;\r\n }\r\n \r\n .color-inputs {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n margin-top: 16px;\r\n }\r\n \r\n .color-input-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .color-input-row label {\r\n min-width: 100px;\r\n font-weight: 600;\r\n font-size: 14px;\r\n }\r\n \r\n .color-input-row input[type=\"color\"] {\r\n width: 50px;\r\n height: 40px;\r\n border: none;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n }\r\n \r\n .color-input-row input[type=\"text\"] {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: 1px solid #ddd;\r\n border-radius: 8px;\r\n font-family: monospace;\r\n font-size: 14px;\r\n }\r\n \r\n .logo-upload {\r\n margin-top: 24px;\r\n padding: 20px;\r\n background: white;\r\n border-radius: 8px;\r\n }\r\n \r\n .upload-section {\r\n margin-bottom: 20px;\r\n }\r\n \r\n .upload-section h3 {\r\n font-size: 16px;\r\n font-weight: 600;\r\n margin-bottom: 12px;\r\n }\r\n \r\n .file-input-wrapper {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .file-input-wrapper input[type=\"file\"] {\r\n display: none;\r\n }\r\n \r\n .upload-button {\r\n padding: 10px 16px;\r\n background: var(--color-background-brand);\r\n color: white;\r\n border: none;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n font-weight: 600;\r\n font-size: 14px;\r\n }\r\n \r\n .upload-button:hover {\r\n opacity: 0.9;\r\n }\r\n \r\n .file-name {\r\n font-size: 14px;\r\n color: #666;\r\n }\r\n \r\n .reset-button {\r\n padding: 8px 12px;\r\n background: #f5f5f5;\r\n color: #666;\r\n border: 1px solid #ddd;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n }\r\n `],\r\n template: `\r\n <ion-header>\r\n <ion-toolbar>\r\n <ion-title>Whitelabel Demo</ion-title>\r\n </ion-toolbar>\r\n </ion-header>\r\n \r\n <ion-content>\r\n <div class=\"demo-container\">\r\n <!-- Logo Section -->\r\n <div class=\"demo-section\">\r\n <h2>Logos</h2>\r\n <div class=\"logo-showcase\">\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Full Logo (md)</p>\r\n <ds-logo variant=\"full\" size=\"md\" />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Logomark (sm)</p>\r\n <ds-logo variant=\"mark\" size=\"sm\" />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Logomark (md)</p>\r\n <ds-logo variant=\"mark\" size=\"md\" />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Logomark (lg)</p>\r\n <ds-logo variant=\"mark\" size=\"lg\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Logo Upload Section -->\r\n <div class=\"logo-upload\">\r\n <div class=\"upload-section\">\r\n <h3>Upload Full Logo</h3>\r\n <div class=\"file-input-wrapper\">\r\n <input \r\n #fullLogoInput\r\n type=\"file\" \r\n accept=\"image/*\"\r\n (change)=\"handleFullLogoUpload($event)\"\r\n />\r\n <button class=\"upload-button\" (click)=\"fullLogoInput.click()\">\r\n Choose File\r\n </button>\r\n @if (uploadedFullLogoName) {\r\n <span class=\"file-name\">{{ uploadedFullLogoName }}</span>\r\n }\r\n @if (uploadedFullLogoName) {\r\n <button class=\"reset-button\" (click)=\"resetFullLogo()\">Reset</button>\r\n }\r\n </div>\r\n </div>\r\n \r\n <div class=\"upload-section\">\r\n <h3>Upload Logomark</h3>\r\n <div class=\"file-input-wrapper\">\r\n <input \r\n #logomarkInput\r\n type=\"file\" \r\n accept=\"image/*\"\r\n (change)=\"handleLogomarkUpload($event)\"\r\n />\r\n <button class=\"upload-button\" (click)=\"logomarkInput.click()\">\r\n Choose File\r\n </button>\r\n @if (uploadedLogomarkName) {\r\n <span class=\"file-name\">{{ uploadedLogomarkName }}</span>\r\n }\r\n @if (uploadedLogomarkName) {\r\n <button class=\"reset-button\" (click)=\"resetLogomark()\">Reset</button>\r\n }\r\n </div>\r\n </div>\r\n \r\n <p style=\"font-size: 12px; color: #999; margin-top: 12px;\">\r\n Tip: Use SVG or PNG files with transparent backgrounds for best results\r\n </p>\r\n </div>\r\n </div>\r\n \r\n <!-- Avatar with Badge Section -->\r\n <div class=\"demo-section\">\r\n <h2>Avatar with Logo Badge</h2>\r\n <div class=\"avatar-showcase\">\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Small</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'sm'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Medium</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'md'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">Large</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'lg'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n <div>\r\n <p style=\"margin-bottom: 8px; font-size: 12px; color: #666;\">X-Large</p>\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'JD'\"\r\n [size]=\"'xl'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Color Section -->\r\n <div class=\"demo-section\">\r\n <h2>Brand Colors</h2>\r\n <div class=\"color-demo\">\r\n <p style=\"margin-bottom: 8px; color: #666;\">Current brand colors:</p>\r\n <div class=\"color-swatch\">\r\n <div class=\"swatch swatch--primary\">\r\n Primary<br/>\r\n <span style=\"font-size: 11px; opacity: 0.9;\">{{ whitelabelService.primaryColor() }}</span>\r\n </div>\r\n <div class=\"swatch swatch--secondary\">\r\n Secondary<br/>\r\n <span style=\"font-size: 11px; opacity: 0.9;\">{{ whitelabelService.secondaryColor() }}</span>\r\n </div>\r\n </div>\r\n \r\n <!-- Custom Color Inputs -->\r\n <div class=\"color-inputs\">\r\n <div class=\"color-input-row\">\r\n <label>Primary:</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customPrimaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customPrimaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n placeholder=\"#6B5FF5\"\r\n />\r\n </div>\r\n <div class=\"color-input-row\">\r\n <label>Secondary:</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSecondaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSecondaryColor\"\r\n (change)=\"applyCustomColors()\"\r\n placeholder=\"#221a4c\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Theme Switcher -->\r\n <div class=\"demo-section\">\r\n <h2>Switch Organization Theme</h2>\r\n <div class=\"button-group\">\r\n <ion-button (click)=\"applyDefaultTheme()\">\r\n Default (Purple)\r\n </ion-button>\r\n <ion-button (click)=\"applyBlueTheme()\">\r\n Blue Theme\r\n </ion-button>\r\n <ion-button (click)=\"applyGreenTheme()\">\r\n Green Theme\r\n </ion-button>\r\n <ion-button (click)=\"applyOrangeTheme()\">\r\n Orange Theme\r\n </ion-button>\r\n </div>\r\n </div>\r\n \r\n <!-- Current Config -->\r\n <div class=\"demo-section\">\r\n <h2>Current Configuration</h2>\r\n <div class=\"current-config\">\r\n <pre>{{ configJson() }}</pre>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class WhitelabelDemoPage implements OnInit {\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n // Custom color inputs\r\n customPrimaryColor = '#6B5FF5';\r\n customSecondaryColor = '#221a4c';\r\n \r\n // Logo upload state\r\n uploadedFullLogoName = '';\r\n uploadedLogomarkName = '';\r\n \r\n ngOnInit() {\r\n console.log('Whitelabel Demo Page initialized');\r\n // Initialize custom colors with current values\r\n this.customPrimaryColor = this.whitelabelService.primaryColor();\r\n this.customSecondaryColor = this.whitelabelService.secondaryColor();\r\n }\r\n \r\n handleFullLogoUpload(event: Event) {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files[0]) {\r\n const file = input.files[0];\r\n this.uploadedFullLogoName = file.name;\r\n \r\n // Convert to data URL\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const dataUrl = e.target?.result as string;\r\n this.whitelabelService.updateConfig({\r\n logoUrl: dataUrl\r\n });\r\n };\r\n reader.readAsDataURL(file);\r\n }\r\n }\r\n \r\n handleLogomarkUpload(event: Event) {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files[0]) {\r\n const file = input.files[0];\r\n this.uploadedLogomarkName = file.name;\r\n \r\n // Convert to data URL\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const dataUrl = e.target?.result as string;\r\n this.whitelabelService.updateConfig({\r\n logoMarkUrl: dataUrl\r\n });\r\n };\r\n reader.readAsDataURL(file);\r\n }\r\n }\r\n \r\n resetFullLogo() {\r\n this.uploadedFullLogoName = '';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/assets/logos/propbinder-logo.svg'\r\n });\r\n }\r\n \r\n resetLogomark() {\r\n this.uploadedLogomarkName = '';\r\n this.whitelabelService.updateConfig({\r\n logoMarkUrl: '/assets/logos/propbinder-logomark.svg'\r\n });\r\n }\r\n \r\n configJson() {\r\n return JSON.stringify(this.whitelabelService.config(), null, 2);\r\n }\r\n \r\n applyDefaultTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#6B5FF5',\r\n secondaryColor: '#221a4c',\r\n organizationName: 'Propbinder',\r\n organizationId: 'default'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyBlueTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#2563eb',\r\n secondaryColor: '#3b82f6',\r\n organizationName: 'Blue Corp',\r\n organizationId: 'blue-corp'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyGreenTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#16a34a',\r\n secondaryColor: '#22c55e',\r\n organizationName: 'Green Industries',\r\n organizationId: 'green-industries'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyOrangeTheme() {\r\n this.whitelabelService.updateConfig({\r\n primaryColor: '#ea580c',\r\n secondaryColor: '#f97316',\r\n organizationName: 'Orange Solutions',\r\n organizationId: 'orange-solutions'\r\n });\r\n this.updateCustomColorInputs();\r\n }\r\n \r\n applyCustomColors() {\r\n this.whitelabelService.updateColors(\r\n this.customPrimaryColor,\r\n this.customSecondaryColor\r\n );\r\n }\r\n \r\n private updateCustomColorInputs() {\r\n this.customPrimaryColor = this.whitelabelService.primaryColor();\r\n this.customSecondaryColor = this.whitelabelService.secondaryColor();\r\n }\r\n}\r\n\r\n","/* Auto-generated. Do not edit. */\nexport * from './components';\nexport * from './pages';\nexport * from './animations/page-transitions';\nexport * from './services/user.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.DsMobileLongPressDirective","PostContentComponent","PostTextComponent","PostMediaComponent","PostAttachmentsComponent","PostActionsComponent","ActionLikeComponent","ActionCommentComponent","i1","i2","DsMobileTabsComponent","i1.DsMobileLightboxService","DsMobileCommentActionsBottomSheetComponent","i2.DsMobileLightboxService","i3.DsMobileBottomSheetService","i4","i1.DsMobileHandbookDetailModalService","DsMobilePostActionsBottomSheetComponent","i2.DsMobileBottomSheetService","i3.DsMobileLightboxService","i4.DsMobilePostDetailModalService","i5.UserService","i1.UserService","i2.UserService","i3"],"mappings":"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"}