All files / app/services brand.service.ts

58.33% Statements 42/72
100% Branches 2/2
33.33% Functions 2/6
58.33% Lines 42/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 731x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 38x 38x 38x 38x 38x 38x 38x 38x 38x 38x 38x                               38x 38x 38x 114x 114x 38x 38x 38x                     38x 38x 38x     38x 38x       38x  
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap, shareReplay } from 'rxjs/operators';
import { environment } from '@environments/environment';
 
export interface Brand {
	name: string;
	subdomain: string;
	logo_url: string;
	white_label_color: string;
	primary_text_color: string;
	secondary_text_color: string;
}
 
@Injectable({ providedIn: 'root' })
export class BrandService {
	private http = inject(HttpClient);
 
	// ===== STATE =====
	private currentBrandSubject = new BehaviorSubject<Brand | null>(null);
	currentBrand$ = this.currentBrandSubject.asObservable();
 
	// Prevent duplicate API calls
	private brandRequest$?: Observable<Brand>;
 
	// ===== LOAD BRAND =====
	loadBrand(subdomain: string): Observable<Brand> {
		const url = `${environment.apiBaseUrl}/v5/agency/white_label?subdomain=${subdomain}`;

		// Prevent duplicate calls
		if (!this.brandRequest$) {
			this.brandRequest$ = this.http.get<Brand>(url).pipe(
				tap((brand) => {
					this.currentBrandSubject.next(brand);
					this.applyTheme(brand); // 🔥 auto-apply theme
				}),
				shareReplay(1),
			);
		}

		return this.brandRequest$;
	}
 
	// ===== SYNC GETTER =====
	getBrand(): Brand | null {
		return this.currentBrandSubject.value;
	}
 
	// ===== THEME APPLIER =====
	private applyTheme(brand: Brand | null): void {
		if (typeof window === 'undefined') return;

		const root = document.documentElement;

		root.style.setProperty('--primary-color', brand?.primary_text_color || '#02af97');

		root.style.setProperty('--secondary-color', brand?.secondary_text_color || '#c4ebe2');

		root.style.setProperty('--text-color', brand?.white_label_color || '#fff');
	}
 
	// ===== RESET / DEFAULT =====
	applyDefaultTheme(): void {
		this.applyTheme(null);
	}
 
	clearCache(): void {
		this.brandRequest$ = undefined;
		this.currentBrandSubject.next(null);
	}
}