neues Admin UI Layout eingeführt. Alle Tests auf den neusten Stand gebracht.

This commit is contained in:
Codex Agent
2025-12-30 10:24:06 +01:00
parent 902e78cae9
commit efe2f25b3e
85 changed files with 95235 additions and 19197 deletions

View File

@@ -29,7 +29,7 @@ import { isAuthError } from '../auth/tokens';
import { getApiErrorMessage } from '../lib/apiError';
import { MobileSheet } from './components/Sheet';
import { useEventContext } from '../context/EventContext';
import { useTheme } from '@tamagui/core';
import { useAdminTheme } from './theme';
import { buildLimitWarnings } from '../lib/limitWarnings';
import { adminPath } from '../constants';
import { scopeDefaults, selectAddonKeyForScope } from './addons';
@@ -88,15 +88,9 @@ export default function MobileEventPhotosPage() {
const [queuedActions, setQueuedActions] = React.useState<PhotoModerationAction[]>(() => loadPhotoQueue());
const online = useOnlineStatus();
const syncingQueueRef = React.useRef(false);
const theme = useTheme();
const text = String(theme.color?.val ?? '#111827');
const muted = String(theme.gray?.val ?? '#4b5563');
const border = String(theme.borderColor?.val ?? '#e5e7eb');
const infoBg = String(theme.blue3?.val ?? '#e8f1ff');
const infoBorder = String(theme.blue6?.val ?? '#bfdbfe');
const danger = String(theme.red10?.val ?? '#b91c1c');
const surface = String(theme.surface?.val ?? '#ffffff');
const backdrop = String(theme.gray12?.val ?? '#0f172a');
const { text, muted, border, accentSoft, accent, danger, surface, backdrop, primary } = useAdminTheme();
const infoBg = accentSoft;
const infoBorder = accent;
const basePhotosPath = slug ? adminPath(`/mobile/events/${slug}/photos`) : adminPath('/mobile/events');
const photoQuery = React.useMemo(() => {
@@ -858,9 +852,9 @@ export default function MobileEventPhotosPage() {
borderRadius={999}
alignItems="center"
justifyContent="center"
backgroundColor={isSelected ? String(theme.primary?.val ?? '#007AFF') : 'rgba(255,255,255,0.85)'}
backgroundColor={isSelected ? primary : 'rgba(255,255,255,0.85)'}
borderWidth={1}
borderColor={isSelected ? String(theme.primary?.val ?? '#007AFF') : border}
borderColor={isSelected ? primary : border}
>
{isSelected ? <Check size={14} color="white" /> : null}
</XStack>
@@ -896,7 +890,7 @@ export default function MobileEventPhotosPage() {
backgroundColor={surface}
borderWidth={1}
borderColor={border}
shadowColor="#0f172a"
shadowColor={backdrop}
shadowOpacity={0.18}
shadowRadius={16}
shadowOffset={{ width: 0, height: 8 }}
@@ -908,7 +902,7 @@ export default function MobileEventPhotosPage() {
{t('mobilePhotos.selectedCount', '{{count}} selected', { count: selectedIds.length })}
</Text>
<Pressable onPress={() => clearSelection()}>
<Text fontSize="$sm" color={String(theme.primary?.val ?? '#007AFF')} fontWeight="700">
<Text fontSize="$sm" color={primary} fontWeight="700">
{t('common.clear', 'Clear')}
</Text>
</Pressable>
@@ -1167,7 +1161,7 @@ type SwipeActionConfig = {
function PhotoSwipeCard({ photo, disabled = false, onOpen, onModerate, children }: PhotoSwipeCardProps) {
const { t } = useTranslation('management');
const theme = useTheme();
const { successBg, successText, dangerBg, dangerText, infoBg, infoText } = useAdminTheme();
const controls = useAnimationControls();
const dragged = React.useRef(false);
const leftAction = resolvePhotoSwipeAction(photo, 'left');
@@ -1181,23 +1175,23 @@ function PhotoSwipeCard({ photo, disabled = false, onOpen, onModerate, children
if (action === 'approve') {
return {
label: t('photos.actions.approve', 'Approve'),
bg: String(theme.green3?.val ?? '#dcfce7'),
text: String(theme.green11?.val ?? '#166534'),
bg: successBg,
text: successText,
icon: Check,
};
}
if (action === 'hide') {
return {
label: t('photos.actions.hide', 'Hide'),
bg: String(theme.red3?.val ?? '#fee2e2'),
text: String(theme.red11?.val ?? '#b91c1c'),
bg: dangerBg,
text: dangerText,
icon: EyeOff,
};
}
return {
label: t('photos.actions.show', 'Show'),
bg: String(theme.blue3?.val ?? '#dbeafe'),
text: String(theme.blue11?.val ?? '#1d4ed8'),
bg: infoBg,
text: infoText,
icon: Eye,
};
};
@@ -1509,10 +1503,11 @@ function MobileAddonsPicker({
}
function EventAddonList({ addons, textColor, mutedColor }: { addons: EventAddonSummary[]; textColor: string; mutedColor: string }) {
const { border } = useAdminTheme();
return (
<YStack space="$2">
{addons.map((addon) => (
<MobileCard key={addon.id} borderColor="#e5e7eb" space="$1.5">
<MobileCard key={addon.id} borderColor={border} space="$1.5">
<XStack alignItems="center" justifyContent="space-between">
<Text fontSize="$sm" fontWeight="700" color={textColor}>
{addon.label ?? addon.key}