/** * ConsentServiceBase — Angular Service Wrapper. * * Phase 4: extracted from angular/index.ts. */ import { ConsentManager } from '../core/ConsentManager'; import type { ConsentCategories, ConsentCategory, ConsentConfig, ConsentState, } from '../types'; import type { IConsentService } from './interface'; /** * ConsentService - Angular Service Wrapper * * Diese Klasse kann als Angular Service registriert werden: * * @example * ```typescript * // consent.service.ts * import { Injectable } from '@angular/core'; * import { ConsentServiceBase } from '@breakpilot/consent-sdk/angular'; * * @Injectable({ providedIn: 'root' }) * export class ConsentService extends ConsentServiceBase { * constructor() { * super({ * apiEndpoint: environment.consentApiEndpoint, * siteId: environment.siteId, * }); * } * } * ``` */ export class ConsentServiceBase implements IConsentService { private manager: ConsentManager; private _consent: ConsentState | null = null; private _isInitialized = false; private _isLoading = true; private _isBannerVisible = false; // Callbacks fuer Angular Change Detection private changeCallbacks: Array<(consent: ConsentState) => void> = []; private bannerShowCallbacks: Array<() => void> = []; private bannerHideCallbacks: Array<() => void> = []; constructor(config: ConsentConfig) { this.manager = new ConsentManager(config); this.setupEventListeners(); this.initialize(); } // --------------------------------------------------------------------------- // Getters // --------------------------------------------------------------------------- get isInitialized(): boolean { return this._isInitialized; } get isLoading(): boolean { return this._isLoading; } get isBannerVisible(): boolean { return this._isBannerVisible; } get consent(): ConsentState | null { return this._consent; } get needsConsent(): boolean { return this.manager.needsConsent(); } // --------------------------------------------------------------------------- // Methods // --------------------------------------------------------------------------- hasConsent(category: ConsentCategory): boolean { return this.manager.hasConsent(category); } async acceptAll(): Promise { await this.manager.acceptAll(); } async rejectAll(): Promise { await this.manager.rejectAll(); } async saveSelection(categories: Partial): Promise { await this.manager.setConsent(categories); this.manager.hideBanner(); } showBanner(): void { this.manager.showBanner(); } hideBanner(): void { this.manager.hideBanner(); } showSettings(): void { this.manager.showSettings(); } // --------------------------------------------------------------------------- // Change Detection Support // --------------------------------------------------------------------------- /** * Registriert Callback fuer Consent-Aenderungen * (fuer Angular Change Detection) */ onConsentChange(callback: (consent: ConsentState) => void): () => void { this.changeCallbacks.push(callback); return () => { const index = this.changeCallbacks.indexOf(callback); if (index > -1) { this.changeCallbacks.splice(index, 1); } }; } /** * Registriert Callback wenn Banner angezeigt wird */ onBannerShow(callback: () => void): () => void { this.bannerShowCallbacks.push(callback); return () => { const index = this.bannerShowCallbacks.indexOf(callback); if (index > -1) { this.bannerShowCallbacks.splice(index, 1); } }; } /** * Registriert Callback wenn Banner ausgeblendet wird */ onBannerHide(callback: () => void): () => void { this.bannerHideCallbacks.push(callback); return () => { const index = this.bannerHideCallbacks.indexOf(callback); if (index > -1) { this.bannerHideCallbacks.splice(index, 1); } }; } // --------------------------------------------------------------------------- // Internal // --------------------------------------------------------------------------- private setupEventListeners(): void { this.manager.on('change', (consent) => { this._consent = consent; this.changeCallbacks.forEach((cb) => cb(consent)); }); this.manager.on('banner_show', () => { this._isBannerVisible = true; this.bannerShowCallbacks.forEach((cb) => cb()); }); this.manager.on('banner_hide', () => { this._isBannerVisible = false; this.bannerHideCallbacks.forEach((cb) => cb()); }); } private async initialize(): Promise { try { await this.manager.init(); this._consent = this.manager.getConsent(); this._isInitialized = true; this._isBannerVisible = this.manager.isBannerVisible(); } catch (error) { console.error('Failed to initialize ConsentManager:', error); } finally { this._isLoading = false; } } }