der tenant admin hat eine neue, mobil unterstützende UI, login redirect funktioniert, typescript fehler wurden bereinigt. Neue Blog Posts von ChatGPT eingebaut, übersetzt von Gemini 2.5

This commit is contained in:
Codex Agent
2025-11-05 19:27:10 +01:00
parent adb93b5f9d
commit c6ac04eb15
44 changed files with 1995 additions and 1949 deletions

View File

@@ -31,7 +31,7 @@ import {
EventToolkitTask,
TenantEvent,
TenantPhoto,
TenantEventStats,
EventStats,
getEvent,
getEventStats,
getEventToolkit,
@@ -62,13 +62,13 @@ type ToolkitState = {
type WorkspaceState = {
event: TenantEvent | null;
stats: TenantEventStats | null;
stats: EventStats | null;
loading: boolean;
busy: boolean;
error: string | null;
};
export default function EventDetailPage({ mode = 'detail' }: EventDetailPageProps): JSX.Element {
export default function EventDetailPage({ mode = 'detail' }: EventDetailPageProps) {
const { slug: slugParam } = useParams<{ slug?: string }>();
const navigate = useNavigate();
const { t } = useTranslation('management');
@@ -325,7 +325,7 @@ function resolveName(name: TenantEvent['name']): string {
return 'Event';
}
function StatusCard({ event, stats, busy, onToggle }: { event: TenantEvent; stats: TenantEventStats | null; busy: boolean; onToggle: () => void }) {
function StatusCard({ event, stats, busy, onToggle }: { event: TenantEvent; stats: EventStats | null; busy: boolean; onToggle: () => void }) {
const { t } = useTranslation('management');
const statusLabel = event.status === 'published'
@@ -355,12 +355,21 @@ function StatusCard({ event, stats, busy, onToggle }: { event: TenantEvent; stat
<div className="rounded-xl border border-pink-100 bg-pink-50/60 p-4 text-xs text-pink-900">
<p className="font-semibold text-pink-700">{t('events.workspace.fields.insights', 'Letzte Aktivität')}</p>
<p>
{t('events.workspace.fields.uploadsTotal', { defaultValue: '{{count}} Uploads gesamt', count: stats.uploads_total })}
{t('events.workspace.fields.uploadsTotal', {
defaultValue: '{{count}} Uploads gesamt',
count: stats.uploads_total ?? stats.total ?? 0,
})}
{' · '}
{t('events.workspace.fields.uploadsToday', { defaultValue: '{{count}} Uploads (24h)', count: stats.uploads_24h })}
{t('events.workspace.fields.uploadsToday', {
defaultValue: '{{count}} Uploads (24h)',
count: stats.uploads_24h ?? stats.recent_uploads ?? 0,
})}
</p>
<p>
{t('events.workspace.fields.likesTotal', { defaultValue: '{{count}} Likes vergeben', count: stats.likes_total })}
{t('events.workspace.fields.likesTotal', {
defaultValue: '{{count}} Likes vergeben',
count: stats.likes_total ?? stats.likes ?? 0,
})}
</p>
</div>
)}
@@ -456,7 +465,7 @@ function QuickActionsCard({ slug, busy, onToggle, navigate }: { slug: string; bu
);
}
function MetricsGrid({ metrics, stats }: { metrics: EventToolkit['metrics'] | null | undefined; stats: TenantEventStats | null }) {
function MetricsGrid({ metrics, stats }: { metrics: EventToolkit['metrics'] | null | undefined; stats: EventStats | null }) {
const { t } = useTranslation('management');
const cards = [
@@ -780,7 +789,8 @@ function resolveEventType(event: TenantEvent): string {
if (typeof event.event_type.name === 'string') {
return event.event_type.name;
}
return event.event_type.name.de ?? event.event_type.name.en ?? Object.values(event.event_type.name)[0] ?? '—';
const translations = event.event_type.name as Record<string, string>;
return translations.de ?? translations.en ?? Object.values(translations)[0] ?? '—';
}
return '—';
}
@@ -801,7 +811,7 @@ function AlertList({ alerts }: { alerts: string[] }) {
);
}
function CalendarIcon(): JSX.Element {
function CalendarIcon() {
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-slate-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
@@ -812,7 +822,7 @@ function CalendarIcon(): JSX.Element {
);
}
function WorkspaceSkeleton(): JSX.Element {
function WorkspaceSkeleton() {
return (
<div className="space-y-6">
<div className="grid gap-6 xl:grid-cols-[minmax(0,1.6fr)_minmax(0,0.6fr)]">
@@ -837,6 +847,6 @@ function WorkspaceSkeleton(): JSX.Element {
);
}
function SkeletonCard(): JSX.Element {
function SkeletonCard() {
return <div className="h-40 animate-pulse rounded-2xl bg-gradient-to-r from-slate-100 via-white to-slate-100" />;
}