73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
import { useEffect } from 'react';
|
|
import { useAppDispatch, useAppSelector } from '@/hooks/redux-hooks';
|
|
import { fetchThemeAsync } from '@/store/themeSlice';
|
|
import apiClient from '@/services/api-client';
|
|
|
|
/**
|
|
* Hook to fetch and apply tenant theme
|
|
* Should be used in tenant admin screens and login
|
|
*/
|
|
export const useTenantTheme = (): void => {
|
|
const dispatch = useAppDispatch();
|
|
const { faviconUrl, isInitialized, isLoading } = useAppSelector((state) => state.theme);
|
|
|
|
useEffect(() => {
|
|
// Only fetch if not already initialized
|
|
if (!isInitialized && !isLoading) {
|
|
dispatch(fetchThemeAsync());
|
|
}
|
|
}, [dispatch, isInitialized, isLoading]);
|
|
|
|
// Apply favicon
|
|
useEffect(() => {
|
|
if (!faviconUrl) return;
|
|
|
|
let isMounted = true;
|
|
let blobUrl: string | null = null;
|
|
|
|
const applyFavicon = async () => {
|
|
const baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api/v1';
|
|
const isBackendUrl = faviconUrl.includes(`${baseUrl}/files/`) && faviconUrl.includes('/preview');
|
|
|
|
let finalUrl = faviconUrl;
|
|
|
|
// If it's a backend URL, fetch it with authentication
|
|
if (isBackendUrl) {
|
|
try {
|
|
const response = await apiClient.get(faviconUrl, { responseType: 'blob' });
|
|
if (isMounted) {
|
|
blobUrl = URL.createObjectURL(response.data);
|
|
finalUrl = blobUrl;
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to fetch authenticated favicon:', err);
|
|
// Fallback to original URL, although it might still fail at browser level
|
|
}
|
|
}
|
|
|
|
if (isMounted) {
|
|
// Remove existing favicon links
|
|
const existingFavicons = document.querySelectorAll("link[rel='icon'], link[rel='shortcut icon']");
|
|
existingFavicons.forEach((favicon) => favicon.remove());
|
|
|
|
// Add new favicon
|
|
const link = document.createElement('link');
|
|
link.rel = 'icon';
|
|
// Try to detect type or default to image/png
|
|
link.type = faviconUrl.endsWith('.ico') ? 'image/x-icon' : 'image/png';
|
|
link.href = finalUrl;
|
|
document.head.appendChild(link);
|
|
}
|
|
};
|
|
|
|
applyFavicon();
|
|
|
|
return () => {
|
|
isMounted = false;
|
|
if (blobUrl) {
|
|
URL.revokeObjectURL(blobUrl);
|
|
}
|
|
};
|
|
}, [faviconUrl]);
|
|
};
|