Das Abschalten des Aufgaben-Modus wird nun sauber in der App reflektiert- die UI passt sich an und der Admin erhält einen Hinweis, dass die Aufgabenverwaltung nicht verfügbar ist

This commit is contained in:
Codex Agent
2025-12-17 13:20:48 +01:00
parent 03e37d7e23
commit efe697f155
15 changed files with 297 additions and 62 deletions

View File

@@ -11,7 +11,7 @@ import { MobileCard, CTAButton, KpiTile, ActionTile, PillBadge } from './compone
import { adminPath } from '../constants';
import { useEventContext } from '../context/EventContext';
import { getEventStats, EventStats, TenantEvent, getEvents } from '../api';
import { formatEventDate, resolveEventDisplayName } from '../lib/events';
import { formatEventDate, resolveEngagementMode, resolveEventDisplayName } from '../lib/events';
import { useTheme } from '@tamagui/core';
export default function MobileDashboardPage() {
@@ -37,6 +37,8 @@ export default function MobileDashboardPage() {
return await getEventStats(activeEvent.slug);
},
});
const tasksEnabled =
resolveEngagementMode(activeEvent ?? undefined) !== 'photo_only';
const locale = i18n.language?.startsWith('en') ? 'en-GB' : 'de-DE';
const { data: dashboardEvents } = useQuery<TenantEvent[]>({
@@ -107,6 +109,7 @@ export default function MobileDashboardPage() {
subtitle={formatEventDate(activeEvent?.event_date, locale) ?? undefined}
>
<FeaturedActions
tasksEnabled={tasksEnabled}
onReviewPhotos={() => activeEvent?.slug && navigate(adminPath(`/mobile/events/${activeEvent.slug}/photos`))}
onManageTasks={() => activeEvent?.slug && navigate(adminPath(`/mobile/events/${activeEvent.slug}/tasks`))}
onShowQr={() => activeEvent?.slug && navigate(adminPath(`/mobile/events/${activeEvent.slug}/qr`))}
@@ -120,9 +123,15 @@ export default function MobileDashboardPage() {
onSettings={() => activeEvent?.slug && navigate(adminPath(`/mobile/events/${activeEvent.slug}`))}
/>
<KpiStrip event={activeEvent} stats={stats} loading={statsLoading} locale={locale} />
<KpiStrip
event={activeEvent}
stats={stats}
loading={statsLoading}
locale={locale}
tasksEnabled={tasksEnabled}
/>
<AlertsAndHints event={activeEvent} stats={stats} />
<AlertsAndHints event={activeEvent} stats={stats} tasksEnabled={tasksEnabled} />
</MobileShell>
);
}
@@ -370,10 +379,12 @@ function EventPickerList({ events, locale, text, muted, border }: { events: Tena
}
function FeaturedActions({
tasksEnabled,
onReviewPhotos,
onManageTasks,
onShowQr,
}: {
tasksEnabled: boolean;
onReviewPhotos: () => void;
onManageTasks: () => void;
onShowQr: () => void;
@@ -394,7 +405,9 @@ function FeaturedActions({
{
key: 'tasks',
label: t('mobileDashboard.tasksLabel', 'Manage tasks & challenges'),
desc: t('mobileDashboard.tasksDesc', 'Assign and track progress'),
desc: tasksEnabled
? t('mobileDashboard.tasksDesc', 'Assign and track progress')
: t('mobileDashboard.tasksDisabledDesc', 'Guests do not see tasks (task mode off)'),
icon: ListTodo,
color: '#22c55e',
action: onManageTasks,
@@ -522,7 +535,19 @@ function SecondaryGrid({
);
}
function KpiStrip({ event, stats, loading, locale }: { event: TenantEvent | null; stats: EventStats | null | undefined; loading: boolean; locale: string }) {
function KpiStrip({
event,
stats,
loading,
locale,
tasksEnabled,
}: {
event: TenantEvent | null;
stats: EventStats | null | undefined;
loading: boolean;
locale: string;
tasksEnabled: boolean;
}) {
const { t } = useTranslation('management');
const theme = useTheme();
const text = String(theme.color12?.val ?? theme.color?.val ?? '#f8fafc');
@@ -530,11 +555,6 @@ function KpiStrip({ event, stats, loading, locale }: { event: TenantEvent | null
if (!event) return null;
const kpis = [
{
label: t('mobileDashboard.kpiTasks', 'Open tasks'),
value: event.tasks_count ?? '—',
icon: ListTodo,
},
{
label: t('mobileDashboard.kpiPhotos', 'Photos'),
value: stats?.uploads_total ?? event.photo_count ?? '—',
@@ -547,6 +567,14 @@ function KpiStrip({ event, stats, loading, locale }: { event: TenantEvent | null
},
];
if (tasksEnabled) {
kpis.unshift({
label: t('mobileDashboard.kpiTasks', 'Open tasks'),
value: event.tasks_count ?? '—',
icon: ListTodo,
});
}
return (
<YStack space="$2">
<Text fontSize="$sm" fontWeight="800" color={text}>
@@ -572,7 +600,7 @@ function KpiStrip({ event, stats, loading, locale }: { event: TenantEvent | null
);
}
function AlertsAndHints({ event, stats }: { event: TenantEvent | null; stats: EventStats | null | undefined }) {
function AlertsAndHints({ event, stats, tasksEnabled }: { event: TenantEvent | null; stats: EventStats | null | undefined; tasksEnabled: boolean }) {
const { t } = useTranslation('management');
const theme = useTheme();
const text = String(theme.color12?.val ?? theme.color?.val ?? '#f8fafc');
@@ -585,7 +613,7 @@ function AlertsAndHints({ event, stats }: { event: TenantEvent | null; stats: Ev
if (stats?.pending_photos) {
alerts.push(t('mobileDashboard.alertPending', '{{count}} new uploads awaiting moderation', { count: stats.pending_photos }));
}
if (event.tasks_count) {
if (tasksEnabled && event.tasks_count) {
alerts.push(t('mobileDashboard.alertTasks', '{{count}} tasks due or open', { count: event.tasks_count }));
}