Qassure-frontend/src/hooks/useTenantTheme.ts

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]);
};