Add dashboard action colors and admin help translations
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-23 13:14:33 +01:00
parent ead80025fc
commit 55608c311d
6 changed files with 31 additions and 14 deletions

View File

@@ -108,7 +108,8 @@
"loadMore": "Mehr laden", "loadMore": "Mehr laden",
"processing": "Verarbeite …", "processing": "Verarbeite …",
"close": "Schließen", "close": "Schließen",
"reset": "Zurücksetzen" "reset": "Zurücksetzen",
"help": "Hilfe"
}, },
"limits": { "limits": {
"photosTitle": "Foto-Limit", "photosTitle": "Foto-Limit",

View File

@@ -214,7 +214,8 @@
"select": "Auswählen", "select": "Auswählen",
"close": "Schließen", "close": "Schließen",
"reset": "Zurücksetzen", "reset": "Zurücksetzen",
"actionNeeded": "Prüfen" "actionNeeded": "Prüfen",
"help": "Hilfe"
}, },
"photos": { "photos": {
"moderation": { "moderation": {
@@ -2216,6 +2217,11 @@
"label": "Fotoaufgaben & Challenges", "label": "Fotoaufgaben & Challenges",
"helpOn": "Gäste sehen Fotoaufgaben, Challenges und Achievements.", "helpOn": "Gäste sehen Fotoaufgaben, Challenges und Achievements.",
"helpOff": "Fotoaufgaben-Modus aus: Gäste sehen nur den Fotofeed." "helpOff": "Fotoaufgaben-Modus aus: Gäste sehen nur den Fotofeed."
},
"uploadVisibility": {
"label": "Uploads sofort sichtbar",
"helpOn": "Neue Gast-Uploads erscheinen sofort in der Galerie (Security-Scan läuft im Hintergrund).",
"helpOff": "Uploads werden zunächst geprüft und erscheinen nach Freigabe."
} }
}, },
"actions": { "actions": {

View File

@@ -108,7 +108,8 @@
"loadMore": "Load more", "loadMore": "Load more",
"processing": "Processing…", "processing": "Processing…",
"close": "Close", "close": "Close",
"reset": "Reset" "reset": "Reset",
"help": "Help"
}, },
"limits": { "limits": {
"photosTitle": "Photo limit", "photosTitle": "Photo limit",

View File

@@ -210,7 +210,8 @@
"select": "Select", "select": "Select",
"close": "Close", "close": "Close",
"reset": "Reset", "reset": "Reset",
"actionNeeded": "Review" "actionNeeded": "Review",
"help": "Help"
}, },
"photos": { "photos": {
"moderation": { "moderation": {
@@ -2218,6 +2219,11 @@
"label": "Photo tasks & challenges", "label": "Photo tasks & challenges",
"helpOn": "Guests can see photo tasks, challenges and achievements.", "helpOn": "Guests can see photo tasks, challenges and achievements.",
"helpOff": "Photo tasks mode is off: guests only see the photo feed." "helpOff": "Photo tasks mode is off: guests only see the photo feed."
},
"uploadVisibility": {
"label": "Uploads visible immediately",
"helpOn": "New guest uploads appear in the gallery right away (security scan runs in the background).",
"helpOff": "Uploads are reviewed first and appear after approval."
} }
}, },
"actions": { "actions": {

View File

@@ -22,7 +22,7 @@ import { useEventContext } from '../context/EventContext';
import { getEventStats, EventStats, TenantEvent, getEventPhotos, TenantPhoto, updateEvent } from '../api'; import { getEventStats, EventStats, TenantEvent, getEventPhotos, TenantPhoto, updateEvent } from '../api';
import { formatEventDate } from '../lib/events'; import { formatEventDate } from '../lib/events';
import { useAuth } from '../auth/context'; import { useAuth } from '../auth/context';
import { useAdminTheme } from './theme'; import { ADMIN_ACTION_COLORS, useAdminTheme } from './theme';
import { buildLimitWarnings } from '../lib/limitWarnings'; import { buildLimitWarnings } from '../lib/limitWarnings';
import { withAlpha } from './components/colors'; import { withAlpha } from './components/colors';
import { useEventReadiness } from './hooks/useEventReadiness'; import { useEventReadiness } from './hooks/useEventReadiness';
@@ -606,15 +606,15 @@ function UnifiedToolGrid({ event, navigate, permissions, isMember, isCompleted }
const operationsItems = [ const operationsItems = [
!isCompleted ? { label: t('management:invites.badge', 'QR Codes'), icon: QrCode, path: `/mobile/events/${slug}/qr`, color: '#10B981' } : null, !isCompleted ? { label: t('management:invites.badge', 'QR Codes'), icon: QrCode, path: `/mobile/events/${slug}/qr`, color: '#10B981' } : null,
{ label: t('management:events.quick.guests', 'Guests'), icon: Users, path: `/mobile/events/${slug}/members`, color: theme.text }, { label: t('management:events.quick.guests', 'Guests'), icon: Users, path: `/mobile/events/${slug}/members`, color: ADMIN_ACTION_COLORS.guests },
!isCompleted ? { label: t('management:events.quick.guestMessages', 'Messages'), icon: Megaphone, path: `/mobile/events/${slug}/guest-notifications`, color: theme.text } : null, !isCompleted ? { label: t('management:events.quick.guestMessages', 'Messages'), icon: Megaphone, path: `/mobile/events/${slug}/guest-notifications`, color: ADMIN_ACTION_COLORS.guestMessages } : null,
!isCompleted ? { label: t('events.branding.titleShort', 'Branding'), icon: Layout, path: `/mobile/events/${slug}/branding`, color: theme.text } : null, !isCompleted ? { label: t('events.branding.titleShort', 'Branding'), icon: Layout, path: `/mobile/events/${slug}/branding`, color: ADMIN_ACTION_COLORS.branding } : null,
].filter((item): item is { label: string; icon: any; path: string; color?: string } => Boolean(item)); ].filter((item): item is { label: string; icon: any; path: string; color?: string } => Boolean(item));
const adminItems = [ const adminItems = [
{ label: t('management:mobileDashboard.shortcutAnalytics', 'Analytics'), icon: TrendingUp, path: `/mobile/events/${slug}/analytics` }, { label: t('management:mobileDashboard.shortcutAnalytics', 'Analytics'), icon: TrendingUp, path: `/mobile/events/${slug}/analytics`, color: ADMIN_ACTION_COLORS.analytics },
!isCompleted ? { label: t('events.recap.exportTitleShort', 'Exports'), icon: Download, path: `/mobile/exports` } : null, !isCompleted ? { label: t('events.recap.exportTitleShort', 'Exports'), icon: Download, path: `/mobile/exports`, color: ADMIN_ACTION_COLORS.recap } : null,
{ label: t('management:mobileProfile.settings', 'Settings'), icon: Settings, path: `/mobile/events/${slug}/edit` }, { label: t('management:mobileProfile.settings', 'Settings'), icon: Settings, path: `/mobile/events/${slug}/edit`, color: ADMIN_ACTION_COLORS.settings },
].filter((item): item is { label: string; icon: any; path: string; color?: string } => Boolean(item)); ].filter((item): item is { label: string; icon: any; path: string; color?: string } => Boolean(item));
const sections = [ const sections = [

View File

@@ -4,6 +4,7 @@ import { HelpCircle } from 'lucide-react';
import { XStack } from '@tamagui/stacks'; import { XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text'; import { SizableText as Text } from '@tamagui/text';
import { Pressable } from '@tamagui/react-native-web-lite'; import { Pressable } from '@tamagui/react-native-web-lite';
import { useTranslation } from 'react-i18next';
import { adminPath } from '../../constants'; import { adminPath } from '../../constants';
import { useAdminTheme } from '../theme'; import { useAdminTheme } from '../theme';
@@ -13,14 +14,16 @@ type ContextHelpLinkProps = {
label?: string; label?: string;
}; };
export function ContextHelpLink({ slug, label = 'Help' }: ContextHelpLinkProps) { export function ContextHelpLink({ slug, label }: ContextHelpLinkProps) {
const navigate = useNavigate(); const navigate = useNavigate();
const { t } = useTranslation('common');
const { border, primary, surfaceMuted, textStrong } = useAdminTheme(); const { border, primary, surfaceMuted, textStrong } = useAdminTheme();
const resolvedLabel = label ?? t('common.help', 'Help');
return ( return (
<Pressable <Pressable
onPress={() => navigate(adminPath(`/mobile/help/${encodeURIComponent(slug)}`))} onPress={() => navigate(adminPath(`/mobile/help/${encodeURIComponent(slug)}`))}
aria-label={label} aria-label={resolvedLabel}
> >
<XStack <XStack
alignItems="center" alignItems="center"
@@ -34,7 +37,7 @@ export function ContextHelpLink({ slug, label = 'Help' }: ContextHelpLinkProps)
> >
<HelpCircle size={14} color={primary} /> <HelpCircle size={14} color={primary} />
<Text fontSize="$xs" fontWeight="700" color={textStrong}> <Text fontSize="$xs" fontWeight="700" color={textStrong}>
{label} {resolvedLabel}
</Text> </Text>
</XStack> </XStack>
</Pressable> </Pressable>