mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
@@ -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<BrandingInfo> => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'] })
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user