From e53d805bef91374412e970119d848d8e0f3d3eed Mon Sep 17 00:00:00 2001 From: Egor Date: Mon, 19 Jan 2026 10:31:50 +0300 Subject: [PATCH 1/3] Update branding.ts --- src/api/branding.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/api/branding.ts b/src/api/branding.ts index b61f2e5..0067175 100644 --- a/src/api/branding.ts +++ b/src/api/branding.ts @@ -11,6 +11,30 @@ export interface AnimationEnabled { enabled: boolean } +const BRANDING_CACHE_KEY = 'cabinet_branding' + +// 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 + } +} + export const brandingApi = { // Get current branding (public, no auth required) getBranding: async (): Promise => { From cde7909925414dddc74a53d4b17ac259d7354b03 Mon Sep 17 00:00:00 2001 From: Egor Date: Mon, 19 Jan 2026 10:32:29 +0300 Subject: [PATCH 2/3] Update Layout.tsx --- src/components/layout/Layout.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 8ab2c62..01cfd90 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -9,7 +9,7 @@ import TicketNotificationBell from '../TicketNotificationBell' import AnimatedBackground from '../AnimatedBackground' import { contestsApi } from '../../api/contests' import { pollsApi } from '../../api/polls' -import { brandingApi } from '../../api/branding' +import { brandingApi, getCachedBranding, setCachedBranding } from '../../api/branding' import { wheelApi } from '../../api/wheel' import { themeColorsApi } from '../../api/themeColors' import { promoApi } from '../../api/promo' @@ -167,15 +167,21 @@ export default function Layout({ children }: LayoutProps) { } }, [mobileMenuOpen]) - // Fetch branding settings + // Fetch branding settings with localStorage cache for instant load const { data: branding } = useQuery({ queryKey: ['branding'], - queryFn: brandingApi.getBranding, + queryFn: async () => { + const data = await brandingApi.getBranding() + setCachedBranding(data) // Update cache + return data + }, + initialData: getCachedBranding() ?? undefined, // Use cached data immediately staleTime: 60000, // 1 minute + refetchOnWindowFocus: true, retry: 1, }) - // Computed branding values - use fallback only if branding not loaded yet + // Computed branding values - use fallback only if no branding and no cache const appName = branding ? branding.name : FALLBACK_NAME // Empty string is valid (logo-only mode) const logoLetter = branding?.logo_letter || FALLBACK_LOGO const hasCustomLogo = branding?.has_custom_logo || false From 164ec7a38058794e298d569618eecd1a36226801 Mon Sep 17 00:00:00 2001 From: Egor Date: Mon, 19 Jan 2026 10:32:58 +0300 Subject: [PATCH 3/3] Update AdminSettings.tsx --- src/pages/AdminSettings.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pages/AdminSettings.tsx b/src/pages/AdminSettings.tsx index ccd878a..6080066 100644 --- a/src/pages/AdminSettings.tsx +++ b/src/pages/AdminSettings.tsx @@ -3,7 +3,7 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' import { Link } from 'react-router-dom' import { adminSettingsApi, SettingDefinition, SettingCategorySummary } from '../api/adminSettings' -import { brandingApi } from '../api/branding' +import { brandingApi, setCachedBranding } from '../api/branding' import { setCachedAnimationEnabled } from '../components/AnimatedBackground' import { themeColorsApi } from '../api/themeColors' import { DEFAULT_THEME_COLORS, DEFAULT_ENABLED_THEMES } from '../types/theme' @@ -882,7 +882,8 @@ export default function AdminSettings() { const updateNameMutation = useMutation({ mutationFn: (name: string) => brandingApi.updateName(name), - onSuccess: () => { + onSuccess: (data) => { + setCachedBranding(data) // Update cache immediately queryClient.invalidateQueries({ queryKey: ['branding'] }) setEditingName(false) }, @@ -890,14 +891,16 @@ export default function AdminSettings() { const uploadLogoMutation = useMutation({ mutationFn: (file: File) => brandingApi.uploadLogo(file), - onSuccess: () => { + onSuccess: (data) => { + setCachedBranding(data) // Update cache immediately queryClient.invalidateQueries({ queryKey: ['branding'] }) }, }) const deleteLogoMutation = useMutation({ mutationFn: () => brandingApi.deleteLogo(), - onSuccess: () => { + onSuccess: (data) => { + setCachedBranding(data) // Update cache immediately queryClient.invalidateQueries({ queryKey: ['branding'] }) }, })