diff --git a/.gitignore b/.gitignore index 76b7fdd..22bdbc6 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,10 @@ coverage/ *.tmp *.temp +# Backup and test directories +backups/ +test-archiver/ + # Keep directory structure !storage/events/active/.gitkeep !storage/events/archived/.gitkeep diff --git a/backend/src/routes/publicSettings.js b/backend/src/routes/publicSettings.js index 1a8c5ba..388268f 100644 --- a/backend/src/routes/publicSettings.js +++ b/backend/src/routes/publicSettings.js @@ -45,6 +45,7 @@ router.get('/', async (req, res) => { theme_config: settingsObject.theme_config || null, default_language: settingsObject.general_default_language || 'en', enable_analytics: settingsObject.general_enable_analytics !== false, + general_date_format: settingsObject.general_date_format || 'PPP', enable_recaptcha: settingsObject.security_enable_recaptcha === true || settingsObject.security_enable_recaptcha === 'true', recaptcha_site_key: settingsObject.security_recaptcha_site_key || null, maintenance_mode: settingsObject.general_maintenance_mode === true || settingsObject.general_maintenance_mode === 'true', diff --git a/frontend/src/config/api.ts b/frontend/src/config/api.ts index 1539c44..f565956 100644 --- a/frontend/src/config/api.ts +++ b/frontend/src/config/api.ts @@ -83,8 +83,8 @@ api.interceptors.response.use( } if (error.response?.status === 401) { - // Check if it's an admin route - const isAdminRoute = error.config?.url?.includes('/admin'); + // Check if it's an admin route (but not public endpoints) + const isAdminRoute = error.config?.url?.includes('/admin') && !error.config?.url?.includes('/public/'); const currentPath = window.location.pathname; if (isAdminRoute) { diff --git a/frontend/src/hooks/useLocalizedDate.ts b/frontend/src/hooks/useLocalizedDate.ts index 4ba5af3..1f16d64 100644 --- a/frontend/src/hooks/useLocalizedDate.ts +++ b/frontend/src/hooks/useLocalizedDate.ts @@ -2,16 +2,17 @@ import { useTranslation } from 'react-i18next'; import { format as dateFnsFormat, formatDistanceToNow as dateFnsFormatDistanceToNow } from 'date-fns'; import { de, enUS } from 'date-fns/locale'; import { useQuery } from '@tanstack/react-query'; -import { settingsService } from '../services/settings.service'; +import { publicSettingsService } from '../services/publicSettings.service'; export const useLocalizedDate = () => { const { i18n } = useTranslation(); - // Fetch admin settings to get the date format + // Fetch public settings to get the date format const { data: settings } = useQuery({ - queryKey: ['admin-settings-general'], - queryFn: () => settingsService.getSettingsByType('general'), + queryKey: ['public-settings'], + queryFn: () => publicSettingsService.getPublicSettings(), staleTime: 5 * 60 * 1000, // Cache for 5 minutes + retry: 1, // Only retry once to avoid blocking the UI }); const getLocale = () => { diff --git a/frontend/src/services/publicSettings.service.ts b/frontend/src/services/publicSettings.service.ts new file mode 100644 index 0000000..eba2821 --- /dev/null +++ b/frontend/src/services/publicSettings.service.ts @@ -0,0 +1,34 @@ +import { api } from '../config/api'; + +export interface PublicSettings { + branding_company_name: string; + branding_company_tagline: string; + branding_support_email: string; + branding_footer_text: string; + branding_watermark_enabled: boolean; + branding_watermark_logo_url: string; + branding_watermark_position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'center'; + branding_watermark_opacity: number; + branding_watermark_size: number; + branding_favicon_url: string; + branding_logo_url: string; + theme_config: any; + default_language: string; + enable_analytics: boolean; + general_date_format: string; + enable_recaptcha: boolean; + recaptcha_site_key: string | null; + maintenance_mode: boolean; + umami_enabled: boolean; + umami_url: string | null; + umami_website_id: string | null; + umami_share_url: string | null; +} + +export const publicSettingsService = { + // Get public settings (no authentication required) + async getPublicSettings(): Promise { + const response = await api.get('/public/settings'); + return response.data; + } +}; \ No newline at end of file