85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
import { useEffect } from 'react'
|
|
import { useQuery } from '@tanstack/react-query'
|
|
import { publicClient } from '../api/publicClient'
|
|
|
|
/** Jawna konfiguracja instancji, ta sama dla panelu i dla stron publicznych. */
|
|
export type PublicConfig = {
|
|
brandName: string
|
|
publicUrl: string
|
|
timezone: string
|
|
/** Adres logo instancji. Pusty oznacza znak domyslny. */
|
|
logoUrl: string
|
|
/** Adres ikony karty przegladarki. Pusty oznacza ikone domyslna. */
|
|
faviconUrl: string
|
|
}
|
|
|
|
const EMPTY: PublicConfig = {
|
|
brandName: '',
|
|
publicUrl: '',
|
|
timezone: 'Europe/Warsaw',
|
|
logoUrl: '',
|
|
faviconUrl: '',
|
|
}
|
|
|
|
/** Klucz cache, do uniewazniania po zapisie ustawien. */
|
|
export const PUBLIC_CONFIG_KEY = ['public-config'] as const
|
|
|
|
/**
|
|
* Pobiera jawna konfiguracje instancji.
|
|
*
|
|
* Zapytanie idzie przez publicClient, wiec dziala tak samo dla niezalogowanego
|
|
* uczestnika i dla obu rol w panelu.
|
|
*
|
|
* Wynik jest buforowany na czas sesji: staleTime Infinity sprawia, ze przejscia
|
|
* miedzy ekranami nie powoduja kolejnych zapytan. Zmiana ustawien w panelu
|
|
* uniewaznia ten klucz recznie, wiec nazwa marki odswieza sie od razu.
|
|
*/
|
|
export function usePublicConfig(): PublicConfig {
|
|
const { data } = useQuery({
|
|
queryKey: PUBLIC_CONFIG_KEY,
|
|
staleTime: Infinity,
|
|
gcTime: Infinity,
|
|
retry: false,
|
|
queryFn: async () => {
|
|
const response = await publicClient.get<PublicConfig>('/public/config')
|
|
return response.data
|
|
},
|
|
})
|
|
|
|
return data ?? EMPTY
|
|
}
|
|
|
|
/** Publiczny adres instancji bez ukosnika na koncu. Pusty, gdy nie ustawiono. */
|
|
export function usePublicUrl(): string {
|
|
const { publicUrl } = usePublicConfig()
|
|
return publicUrl.endsWith('/') ? publicUrl.slice(0, -1) : publicUrl
|
|
}
|
|
|
|
/**
|
|
* Podmienia ikone karty przegladarki na ikone instancji.
|
|
*
|
|
* Wolane raz, w korzeniu aplikacji. Gdy APP_FAVICON_URL jest puste, zostaje
|
|
* ikona domyslna z index.html.
|
|
*/
|
|
export function useInstanceFavicon() {
|
|
const { faviconUrl } = usePublicConfig()
|
|
|
|
useEffect(() => {
|
|
if (!faviconUrl) {
|
|
return
|
|
}
|
|
const link =
|
|
document.querySelector<HTMLLinkElement>('link[rel="icon"]') ??
|
|
document.head.appendChild(Object.assign(document.createElement('link'), { rel: 'icon' }))
|
|
|
|
const previous = link.href
|
|
link.href = faviconUrl
|
|
// typ zdejmujemy, bo adres z ustawien moze wskazywac dowolny format
|
|
link.removeAttribute('type')
|
|
|
|
return () => {
|
|
link.href = previous
|
|
}
|
|
}, [faviconUrl])
|
|
}
|