import apiClient from './client'; export interface BrandingInfo { name: string; logo_url: string | null; logo_letter: string; has_custom_logo: boolean; } export interface AnimationEnabled { enabled: boolean; } export interface FullscreenEnabled { enabled: boolean; } export interface EmailAuthEnabled { enabled: boolean; } export interface AnalyticsCounters { yandex_metrika_id: string; google_ads_id: string; google_ads_label: string; } const BRANDING_CACHE_KEY = 'cabinet_branding'; const LOGO_PRELOADED_KEY = 'cabinet_logo_preloaded'; // Check if logo was already preloaded in this session export const isLogoPreloaded = (): boolean => { try { const cached = getCachedBranding(); if (!cached?.has_custom_logo || !cached?.logo_url) { return false; } const logoUrl = `${import.meta.env.VITE_API_URL || ''}${cached.logo_url}`; const preloaded = sessionStorage.getItem(LOGO_PRELOADED_KEY); return preloaded === logoUrl; } catch { return false; } }; // Get cached branding from localStorage export const getCachedBranding = (): BrandingInfo | null => { try { const cached = localStorage.getItem(BRANDING_CACHE_KEY); if (cached) { return JSON.parse(cached); } } catch { // localStorage not available or invalid JSON } return null; }; // Update branding cache in localStorage export const setCachedBranding = (branding: BrandingInfo) => { try { localStorage.setItem(BRANDING_CACHE_KEY, JSON.stringify(branding)); } catch { // localStorage not available } }; // Preload logo image for instant display export const preloadLogo = (branding: BrandingInfo): Promise => { return new Promise((resolve) => { if (!branding.has_custom_logo || !branding.logo_url) { resolve(); return; } const logoUrl = `${import.meta.env.VITE_API_URL || ''}${branding.logo_url}`; // Check if already preloaded in this session const preloaded = sessionStorage.getItem(LOGO_PRELOADED_KEY); if (preloaded === logoUrl) { resolve(); return; } const img = new Image(); img.onload = () => { sessionStorage.setItem(LOGO_PRELOADED_KEY, logoUrl); resolve(); }; img.onerror = () => resolve(); img.src = logoUrl; }); }; // Initialize logo preload from cache on page load export const initLogoPreload = () => { const cached = getCachedBranding(); if (cached) { preloadLogo(cached); } }; export const brandingApi = { // Get current branding (public, no auth required) getBranding: async (): Promise => { const response = await apiClient.get('/cabinet/branding'); return response.data; }, // Update project name (admin only) updateName: async (name: string): Promise => { const response = await apiClient.put('/cabinet/branding/name', { name }); return response.data; }, // Upload custom logo (admin only) uploadLogo: async (file: File): Promise => { const formData = new FormData(); formData.append('file', file); const response = await apiClient.post('/cabinet/branding/logo', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }); return response.data; }, // Delete custom logo (admin only) deleteLogo: async (): Promise => { const response = await apiClient.delete('/cabinet/branding/logo'); return response.data; }, // Get logo URL (without cache busting - server handles caching via Cache-Control headers) getLogoUrl: (branding: BrandingInfo): string | null => { if (!branding.has_custom_logo || !branding.logo_url) { return null; } return `${import.meta.env.VITE_API_URL || ''}${branding.logo_url}`; }, // Get animation enabled (public, no auth required) getAnimationEnabled: async (): Promise => { const response = await apiClient.get('/cabinet/branding/animation'); return response.data; }, // Update animation enabled (admin only) updateAnimationEnabled: async (enabled: boolean): Promise => { const response = await apiClient.patch('/cabinet/branding/animation', { enabled, }); return response.data; }, // Get fullscreen enabled (public, no auth required) getFullscreenEnabled: async (): Promise => { try { const response = await apiClient.get('/cabinet/branding/fullscreen'); return response.data; } catch { // If endpoint doesn't exist, default to disabled return { enabled: false }; } }, // Update fullscreen enabled (admin only) updateFullscreenEnabled: async (enabled: boolean): Promise => { const response = await apiClient.patch('/cabinet/branding/fullscreen', { enabled, }); return response.data; }, // Get email auth enabled (public, no auth required) getEmailAuthEnabled: async (): Promise => { try { const response = await apiClient.get('/cabinet/branding/email-auth'); return response.data; } catch { // If endpoint doesn't exist, default to enabled return { enabled: true }; } }, // Update email auth enabled (admin only) updateEmailAuthEnabled: async (enabled: boolean): Promise => { const response = await apiClient.patch('/cabinet/branding/email-auth', { enabled, }); return response.data; }, // Get analytics counters (public, no auth required) getAnalyticsCounters: async (): Promise => { try { const response = await apiClient.get('/cabinet/branding/analytics'); return response.data; } catch { return { yandex_metrika_id: '', google_ads_id: '', google_ads_label: '' }; } }, // Update analytics counters (admin only) updateAnalyticsCounters: async (data: Partial): Promise => { const response = await apiClient.patch('/cabinet/branding/analytics', data); return response.data; }, };