fixed errors in branding and invite page, added an error route for better react error display
This commit is contained in:
@@ -21,6 +21,9 @@ import { getContrastingTextColor } from '../../guest/lib/color';
|
||||
import { buildEventTabs } from '../lib/eventTabs';
|
||||
import { ensureFontLoaded, useTenantFonts } from '../lib/fonts';
|
||||
|
||||
const DEFAULT_FONT_VALUE = '__default';
|
||||
const CUSTOM_FONT_VALUE = '__custom';
|
||||
|
||||
type BrandingForm = {
|
||||
useDefault: boolean;
|
||||
palette: {
|
||||
@@ -318,12 +321,12 @@ export default function EventBrandingPage(): React.ReactElement {
|
||||
}
|
||||
|
||||
const resolveFontSelectValue = (current: string): string => {
|
||||
if (!current) return '';
|
||||
return availableFonts.some((font) => font.family === current) ? current : '__custom';
|
||||
if (!current) return DEFAULT_FONT_VALUE;
|
||||
return availableFonts.some((font) => font.family === current) ? current : CUSTOM_FONT_VALUE;
|
||||
};
|
||||
|
||||
const handleFontSelect = (key: 'heading' | 'body', value: string) => {
|
||||
const resolved = value === '__custom' ? '' : value;
|
||||
const resolved = value === CUSTOM_FONT_VALUE || value === DEFAULT_FONT_VALUE ? '' : value;
|
||||
setForm((prev) => ({ ...prev, typography: { ...prev.typography, [key]: resolved } }));
|
||||
const font = availableFonts.find((entry) => entry.family === resolved);
|
||||
if (font) {
|
||||
@@ -446,11 +449,11 @@ export default function EventBrandingPage(): React.ReactElement {
|
||||
<SelectValue placeholder={t('branding.fontDefault', 'Standard (Tenant)')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="">{t('branding.fontDefault', 'Standard (Tenant)')}</SelectItem>
|
||||
<SelectItem value={DEFAULT_FONT_VALUE}>{t('branding.fontDefault', 'Standard (Tenant)')}</SelectItem>
|
||||
{availableFonts.map((font) => (
|
||||
<SelectItem key={font.family} value={font.family}>{font.family}</SelectItem>
|
||||
))}
|
||||
<SelectItem value="__custom">{t('branding.fontCustom', 'Eigene Schrift eingeben')}</SelectItem>
|
||||
<SelectItem value={CUSTOM_FONT_VALUE}>{t('branding.fontCustom', 'Eigene Schrift eingeben')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
@@ -471,11 +474,11 @@ export default function EventBrandingPage(): React.ReactElement {
|
||||
<SelectValue placeholder={t('branding.fontDefault', 'Standard (Tenant)')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="">{t('branding.fontDefault', 'Standard (Tenant)')}</SelectItem>
|
||||
<SelectItem value={DEFAULT_FONT_VALUE}>{t('branding.fontDefault', 'Standard (Tenant)')}</SelectItem>
|
||||
{availableFonts.map((font) => (
|
||||
<SelectItem key={font.family} value={font.family}>{font.family}</SelectItem>
|
||||
))}
|
||||
<SelectItem value="__custom">{t('branding.fontCustom', 'Eigene Schrift eingeben')}</SelectItem>
|
||||
<SelectItem value={CUSTOM_FONT_VALUE}>{t('branding.fontCustom', 'Eigene Schrift eingeben')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
|
||||
@@ -33,6 +33,8 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/component
|
||||
import { cn } from '@/lib/utils';
|
||||
import { ensureFontLoaded, useTenantFonts } from '../../lib/fonts';
|
||||
|
||||
const DEFAULT_FONT_VALUE = '__default';
|
||||
|
||||
import type { EventQrInvite, EventQrInviteLayout } from '../../api';
|
||||
import { authorizedFetch } from '../../auth/tokens';
|
||||
|
||||
@@ -271,19 +273,6 @@ export function InviteLayoutCustomizerPanel({
|
||||
const appliedLayoutRef = React.useRef<string | null>(null);
|
||||
const appliedInviteRef = React.useRef<number | string | null>(null);
|
||||
|
||||
const handleElementFontChange = React.useCallback(
|
||||
(id: string, family: string) => {
|
||||
updateElement(id, { fontFamily: family || null });
|
||||
const font = availableFonts.find((entry) => entry.family === family);
|
||||
if (font) {
|
||||
void ensureFontLoaded(font).then(() => {
|
||||
fabricCanvasRef.current?.requestRenderAll();
|
||||
});
|
||||
}
|
||||
},
|
||||
[availableFonts, updateElement]
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!availableFonts.length || !elements.length) {
|
||||
return;
|
||||
@@ -609,6 +598,19 @@ export function InviteLayoutCustomizerPanel({
|
||||
[commitElements]
|
||||
);
|
||||
|
||||
const handleElementFontChange = React.useCallback(
|
||||
(id: string, family: string) => {
|
||||
updateElement(id, { fontFamily: family || null });
|
||||
const font = availableFonts.find((entry) => entry.family === family);
|
||||
if (font) {
|
||||
void ensureFontLoaded(font).then(() => {
|
||||
fabricCanvasRef.current?.requestRenderAll();
|
||||
});
|
||||
}
|
||||
},
|
||||
[availableFonts, updateElement]
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!invite) {
|
||||
setAvailableLayouts([]);
|
||||
@@ -1340,15 +1342,15 @@ export function InviteLayoutCustomizerPanel({
|
||||
<div className="space-y-2">
|
||||
<Label>{t('invites.customizer.elements.fontFamily', 'Schriftart')}</Label>
|
||||
<Select
|
||||
value={availableFonts.some((font) => font.family === element.fontFamily) ? element.fontFamily ?? '' : ''}
|
||||
onValueChange={(value) => handleElementFontChange(element.id, value)}
|
||||
value={availableFonts.some((font) => font.family === element.fontFamily) ? element.fontFamily ?? DEFAULT_FONT_VALUE : DEFAULT_FONT_VALUE}
|
||||
onValueChange={(value) => handleElementFontChange(element.id, value === DEFAULT_FONT_VALUE ? '' : value)}
|
||||
disabled={fontsLoading}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('invites.customizer.elements.fontPlaceholder', 'Standard')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="">{t('invites.customizer.elements.fontPlaceholder', 'Standard')}</SelectItem>
|
||||
<SelectItem value={DEFAULT_FONT_VALUE}>{t('invites.customizer.elements.fontPlaceholder', 'Standard')}</SelectItem>
|
||||
{availableFonts.map((font) => (
|
||||
<SelectItem key={font.family} value={font.family}>{font.family}</SelectItem>
|
||||
))}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
ADMIN_LOGIN_START_PATH,
|
||||
ADMIN_PUBLIC_LANDING_PATH,
|
||||
} from './constants';
|
||||
import RouteErrorElement from '@/components/RouteErrorElement';
|
||||
const LoginPage = React.lazy(() => import('./pages/LoginPage'));
|
||||
const DashboardPage = React.lazy(() => import('./pages/DashboardPage'));
|
||||
const EventsPage = React.lazy(() => import('./pages/EventsPage'));
|
||||
@@ -86,6 +87,7 @@ export const router = createBrowserRouter([
|
||||
{
|
||||
path: ADMIN_BASE_PATH,
|
||||
element: <Outlet />,
|
||||
errorElement: <RouteErrorElement />,
|
||||
children: [
|
||||
{ index: true, element: <LandingGate /> },
|
||||
{ path: 'login', element: <LoginPage /> },
|
||||
@@ -124,5 +126,6 @@ export const router = createBrowserRouter([
|
||||
{
|
||||
path: '*',
|
||||
element: <Navigate to={ADMIN_PUBLIC_LANDING_PATH} replace />,
|
||||
errorElement: <RouteErrorElement />,
|
||||
},
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user