weitere perfektionierung der neuen mobile app

This commit is contained in:
Codex Agent
2025-12-11 12:18:08 +01:00
parent 7b01a77083
commit b4417db5cd
38 changed files with 4265 additions and 3040 deletions

View File

@@ -11,6 +11,7 @@ import { getEvents, TenantEvent } from '../api';
import { adminPath } from '../constants';
import { isAuthError } from '../auth/tokens';
import { getApiErrorMessage } from '../lib/apiError';
import { useTheme } from '@tamagui/core';
export default function MobileEventsPage() {
const { t } = useTranslation('management');
@@ -19,6 +20,27 @@ export default function MobileEventsPage() {
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState<string | null>(null);
const [query, setQuery] = React.useState('');
const theme = useTheme();
const text = String(theme.color?.val ?? '#111827');
const muted = String(theme.gray?.val ?? '#4b5563');
const subtle = String(theme.gray8?.val ?? '#6b7280');
const border = String(theme.borderColor?.val ?? '#e5e7eb');
const primary = String(theme.primary?.val ?? '#007AFF');
const danger = String(theme.red10?.val ?? '#b91c1c');
const surface = String(theme.surface?.val ?? '#ffffff');
const baseInputStyle = React.useMemo<React.CSSProperties>(
() => ({
width: '100%',
height: 38,
borderRadius: 10,
border: `1px solid ${border}`,
padding: '0 12px',
fontSize: 13,
background: surface,
color: text,
}),
[border, surface, text],
);
React.useEffect(() => {
(async () => {
@@ -41,13 +63,13 @@ export default function MobileEventsPage() {
onBack={() => navigate(-1)}
headerActions={
<Pressable>
<Search size={18} color="#0f172a" />
<Search size={18} color={text} />
</Pressable>
}
>
{error ? (
<MobileCard>
<Text fontWeight="700" color="#b91c1c">
<Text fontWeight="700" color={danger}>
{error}
</Text>
</MobileCard>
@@ -60,16 +82,7 @@ export default function MobileEventsPage() {
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder={t('events.list.search', 'Search events')}
style={{
width: '100%',
height: 38,
borderRadius: 10,
border: '1px solid #e5e7eb',
padding: '0 12px',
fontSize: 13,
background: 'white',
marginBottom: 12,
}}
style={{ ...baseInputStyle, marginBottom: 12 }}
/>
{loading ? (
@@ -83,7 +96,7 @@ export default function MobileEventsPage() {
<Text fontSize="$md" fontWeight="700">
{t('events.list.empty.title', 'Noch kein Event angelegt')}
</Text>
<Text fontSize="$sm" color="#4b5563" textAlign="center">
<Text fontSize="$sm" color={muted} textAlign="center">
{t('events.list.empty.description', 'Starte jetzt mit deinem ersten Event.')}
</Text>
<CTAButton label={t('events.actions.create', 'Create New Event')} onPress={() => navigate(adminPath('/events/new'))} />
@@ -100,6 +113,11 @@ export default function MobileEventsPage() {
<EventRow
key={event.id}
event={event}
text={text}
muted={muted}
subtle={subtle}
border={border}
primary={primary}
onOpen={(slug) => navigate(adminPath(`/mobile/events/${slug}`))}
onEdit={(slug) => navigate(adminPath(`/mobile/events/${slug}/edit`))}
/>
@@ -110,31 +128,49 @@ export default function MobileEventsPage() {
);
}
function EventRow({ event, onOpen, onEdit }: { event: TenantEvent; onOpen: (slug: string) => void; onEdit: (slug: string) => void }) {
function EventRow({
event,
text,
muted,
subtle,
border,
primary,
onOpen,
onEdit,
}: {
event: TenantEvent;
text: string;
muted: string;
subtle: string;
border: string;
primary: string;
onOpen: (slug: string) => void;
onEdit: (slug: string) => void;
}) {
const status = resolveStatus(event);
return (
<MobileCard borderColor="#e2e8f0">
<MobileCard borderColor={border}>
<XStack justifyContent="space-between" alignItems="flex-start" space="$2">
<YStack space="$1">
<Text fontSize="$md" fontWeight="800" color="#111827">
<Text fontSize="$md" fontWeight="800" color={text}>
{renderName(event.name)}
</Text>
<XStack alignItems="center" space="$2">
<CalendarDays size={14} color="#6b7280" />
<Text fontSize="$sm" color="#4b5563">
<CalendarDays size={14} color={subtle} />
<Text fontSize="$sm" color={muted}>
{formatDate(event.event_date)}
</Text>
</XStack>
<XStack alignItems="center" space="$2">
<MapPin size={14} color="#6b7280" />
<Text fontSize="$sm" color="#4b5563">
<MapPin size={14} color={subtle} />
<Text fontSize="$sm" color={muted}>
{resolveLocation(event)}
</Text>
</XStack>
<PillBadge tone={status.tone}>{status.label}</PillBadge>
</YStack>
<Pressable onPress={() => onEdit(event.slug)}>
<Text fontSize="$xl" color="#9ca3af">
<Text fontSize="$xl" color={muted}>
˅
</Text>
</Pressable>
@@ -142,8 +178,8 @@ function EventRow({ event, onOpen, onEdit }: { event: TenantEvent; onOpen: (slug
<Pressable onPress={() => onOpen(event.slug)} style={{ marginTop: 8 }}>
<XStack alignItems="center" justifyContent="flex-start" space="$2">
<Plus size={16} color="#007AFF" />
<Text fontSize="$sm" color="#007AFF" fontWeight="700">
<Plus size={16} color={primary} />
<Text fontSize="$sm" color={primary} fontWeight="700">
Open event
</Text>
</XStack>