neues Admin UI Layout eingeführt. Alle Tests auf den neusten Stand gebracht.
This commit is contained in:
@@ -13,13 +13,13 @@ import { adminPath, ADMIN_WELCOME_BASE_PATH } from '../constants';
|
||||
import { useEventContext } from '../context/EventContext';
|
||||
import { getEventStats, EventStats, TenantEvent, getEvents } from '../api';
|
||||
import { formatEventDate, isBrandingAllowed, resolveEngagementMode, resolveEventDisplayName } from '../lib/events';
|
||||
import { useTheme } from '@tamagui/core';
|
||||
import { useAdminPushSubscription } from './hooks/useAdminPushSubscription';
|
||||
import { useDevicePermissions } from './hooks/useDevicePermissions';
|
||||
import { useInstallPrompt } from './hooks/useInstallPrompt';
|
||||
import { getTourSeen, resolveTourStepKeys, setTourSeen, type TourStepKey } from './lib/mobileTour';
|
||||
import { trackOnboarding } from '../api';
|
||||
import { useAuth } from '../auth/context';
|
||||
import { ADMIN_ACTION_COLORS, ADMIN_MOTION, useAdminTheme } from './theme';
|
||||
|
||||
type DeviceSetupProps = {
|
||||
installPrompt: ReturnType<typeof useInstallPrompt>;
|
||||
@@ -43,13 +43,9 @@ export default function MobileDashboardPage() {
|
||||
const installPrompt = useInstallPrompt();
|
||||
const pushState = useAdminPushSubscription();
|
||||
const devicePermissions = useDevicePermissions();
|
||||
const theme = useTheme();
|
||||
const text = String(theme.color12?.val ?? theme.color?.val ?? '#f8fafc');
|
||||
const muted = String(theme.gray11?.val ?? theme.gray?.val ?? '#cbd5e1');
|
||||
const border = String(theme.borderColor?.val ?? '#334155');
|
||||
const surface = String(theme.surface?.val ?? '#ffffff');
|
||||
const accentSoft = String(theme.blue3?.val ?? '#e0f2fe');
|
||||
const accentText = String(theme.primary?.val ?? '#3b82f6');
|
||||
const { textStrong, muted, border, surface, accentSoft, primary } = useAdminTheme();
|
||||
const text = textStrong;
|
||||
const accentText = primary;
|
||||
|
||||
const { data: stats, isLoading: statsLoading } = useQuery<EventStats | null>({
|
||||
queryKey: ['mobile', 'dashboard', 'stats', activeEvent?.slug],
|
||||
@@ -246,9 +242,9 @@ export default function MobileDashboardPage() {
|
||||
borderRadius={14}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
backgroundColor={String(theme.blue3?.val ?? '#e0f2fe')}
|
||||
backgroundColor={accentSoft}
|
||||
>
|
||||
<activeTourStep.icon size={18} color={String(theme.blue10?.val ?? '#2563eb')} />
|
||||
<activeTourStep.icon size={18} color={accentText} />
|
||||
</XStack>
|
||||
<Text fontSize="$lg" fontWeight="800" color={text}>
|
||||
{activeTourStep.title}
|
||||
@@ -384,13 +380,11 @@ export default function MobileDashboardPage() {
|
||||
|
||||
function DeviceSetupCard({ installPrompt, pushState, devicePermissions, onOpenSettings }: DeviceSetupProps) {
|
||||
const { t } = useTranslation('management');
|
||||
const theme = useTheme();
|
||||
const text = String(theme.color12?.val ?? theme.color?.val ?? '#0f172a');
|
||||
const muted = String(theme.gray11?.val ?? theme.gray?.val ?? '#6b7280');
|
||||
const border = String(theme.borderColor?.val ?? '#e5e7eb');
|
||||
const accent = String(theme.primary?.val ?? '#2563eb');
|
||||
const iconBg = String(theme.blue3?.val ?? '#e0f2fe');
|
||||
const iconColor = String(theme.blue10?.val ?? '#2563eb');
|
||||
const { textStrong, muted, border, primary, accentSoft } = useAdminTheme();
|
||||
const text = textStrong;
|
||||
const accent = primary;
|
||||
const iconBg = accentSoft;
|
||||
const iconColor = primary;
|
||||
|
||||
const items: Array<{
|
||||
key: string;
|
||||
@@ -523,17 +517,13 @@ function DeviceSetupCard({ installPrompt, pushState, devicePermissions, onOpenSe
|
||||
function OnboardingEmptyState({ installPrompt, pushState, devicePermissions, onOpenSettings }: DeviceSetupProps) {
|
||||
const { t } = useTranslation('management');
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
const text = String(theme.color12?.val ?? theme.color?.val ?? '#f8fafc');
|
||||
const muted = String(theme.gray11?.val ?? theme.gray?.val ?? '#cbd5e1');
|
||||
const border = String(theme.borderColor?.val ?? '#cbd5e1');
|
||||
const accent = String(theme.primary?.val ?? '#2563eb');
|
||||
const accentSoft = String(theme.blue3?.val ?? '#e0f2fe');
|
||||
const accentStrong = String(theme.blue10?.val ?? '#1d4ed8');
|
||||
const stepBg = String(theme.gray2?.val ?? '#f8fafc');
|
||||
const stepBorder = String(theme.gray5?.val ?? '#e2e8f0');
|
||||
const supportBg = String(theme.gray2?.val ?? '#f8fafc');
|
||||
const supportBorder = String(theme.gray5?.val ?? '#e2e8f0');
|
||||
const { textStrong, muted, border, accentSoft, accentStrong, surfaceMuted, primary, shadow } = useAdminTheme();
|
||||
const text = textStrong;
|
||||
const accent = primary;
|
||||
const stepBg = surfaceMuted;
|
||||
const stepBorder = border;
|
||||
const supportBg = surfaceMuted;
|
||||
const supportBorder = border;
|
||||
|
||||
const steps = [
|
||||
t('mobileDashboard.emptyStepDetails', 'Add name & date'),
|
||||
@@ -653,7 +643,7 @@ function OnboardingEmptyState({ installPrompt, pushState, devicePermissions, onO
|
||||
borderWidth={1}
|
||||
borderColor={`${border}aa`}
|
||||
backgroundColor="rgba(255,255,255,0.6)"
|
||||
shadowColor="#0f172a"
|
||||
shadowColor={shadow}
|
||||
shadowOpacity={0.04}
|
||||
shadowRadius={10}
|
||||
shadowOffset={{ width: 0, height: 6 }}
|
||||
@@ -785,16 +775,15 @@ function FeaturedActions({
|
||||
onShowQr: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation('management');
|
||||
const theme = useTheme();
|
||||
const text = String(theme.color12?.val ?? theme.color?.val ?? '#f8fafc');
|
||||
const muted = String(theme.gray11?.val ?? theme.gray?.val ?? '#cbd5e1');
|
||||
const { textStrong, muted, subtle } = useAdminTheme();
|
||||
const text = textStrong;
|
||||
const cards = [
|
||||
{
|
||||
key: 'photos',
|
||||
label: t('mobileDashboard.photosLabel', 'Review photos'),
|
||||
desc: t('mobileDashboard.photosDesc', 'Moderate uploads and highlights'),
|
||||
icon: ImageIcon,
|
||||
color: '#0ea5e9',
|
||||
color: ADMIN_ACTION_COLORS.images,
|
||||
action: onReviewPhotos,
|
||||
},
|
||||
{
|
||||
@@ -804,7 +793,7 @@ function FeaturedActions({
|
||||
? t('mobileDashboard.tasksDesc', 'Assign and track progress')
|
||||
: t('mobileDashboard.tasksDisabledDesc', 'Guests do not see tasks (task mode off)'),
|
||||
icon: ListTodo,
|
||||
color: '#22c55e',
|
||||
color: ADMIN_ACTION_COLORS.tasks,
|
||||
action: onManageTasks,
|
||||
},
|
||||
{
|
||||
@@ -812,7 +801,7 @@ function FeaturedActions({
|
||||
label: t('mobileDashboard.qrLabel', 'Show / share QR code'),
|
||||
desc: t('mobileDashboard.qrDesc', 'Posters, cards, and links'),
|
||||
icon: QrCode,
|
||||
color: '#f59e0b',
|
||||
color: ADMIN_ACTION_COLORS.qr,
|
||||
action: onShowQr,
|
||||
},
|
||||
];
|
||||
@@ -834,7 +823,7 @@ function FeaturedActions({
|
||||
{card.desc}
|
||||
</Text>
|
||||
</YStack>
|
||||
<Text fontSize="$xl" color={String(theme.gray9?.val ?? '#94a3b8')}>
|
||||
<Text fontSize="$xl" color={subtle}>
|
||||
˃
|
||||
</Text>
|
||||
</XStack>
|
||||
@@ -859,41 +848,38 @@ function SecondaryGrid({
|
||||
onSettings: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation('management');
|
||||
const theme = useTheme();
|
||||
const text = String(theme.color12?.val ?? theme.color?.val ?? '#f8fafc');
|
||||
const muted = String(theme.gray11?.val ?? theme.gray?.val ?? '#cbd5e1');
|
||||
const border = String(theme.borderColor?.val ?? '#334155');
|
||||
const surface = String(theme.surface?.val ?? '#0b1220');
|
||||
const { textStrong, muted, border, surface, accentSoft, primary } = useAdminTheme();
|
||||
const text = textStrong;
|
||||
const brandingAllowed = isBrandingAllowed(event ?? null);
|
||||
const tiles = [
|
||||
{
|
||||
icon: Users,
|
||||
label: t('mobileDashboard.shortcutGuests', 'Guest management'),
|
||||
color: '#60a5fa',
|
||||
color: ADMIN_ACTION_COLORS.guests,
|
||||
action: onGuests,
|
||||
},
|
||||
{
|
||||
icon: QrCode,
|
||||
label: t('mobileDashboard.shortcutPrints', 'Print & poster downloads'),
|
||||
color: '#fbbf24',
|
||||
color: ADMIN_ACTION_COLORS.qr,
|
||||
action: onPrint,
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
label: t('mobileDashboard.shortcutInvites', 'Team / helper invites'),
|
||||
color: '#a855f7',
|
||||
color: ADMIN_ACTION_COLORS.invites,
|
||||
action: onInvites,
|
||||
},
|
||||
{
|
||||
icon: Settings,
|
||||
label: t('mobileDashboard.shortcutSettings', 'Event settings'),
|
||||
color: '#10b981',
|
||||
color: ADMIN_ACTION_COLORS.success,
|
||||
action: onSettings,
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
label: t('mobileDashboard.shortcutBranding', 'Branding & moderation'),
|
||||
color: '#22d3ee',
|
||||
color: ADMIN_ACTION_COLORS.branding,
|
||||
action: brandingAllowed ? onSettings : undefined,
|
||||
disabled: !brandingAllowed,
|
||||
},
|
||||
@@ -905,7 +891,7 @@ function SecondaryGrid({
|
||||
{t('mobileDashboard.shortcutsTitle', 'Shortcuts')}
|
||||
</Text>
|
||||
<XStack flexWrap="wrap" space="$2">
|
||||
{tiles.map((tile) => (
|
||||
{tiles.map((tile, index) => (
|
||||
<ActionTile
|
||||
key={tile.label}
|
||||
icon={tile.icon}
|
||||
@@ -913,6 +899,7 @@ function SecondaryGrid({
|
||||
color={tile.color}
|
||||
onPress={tile.action}
|
||||
disabled={tile.disabled}
|
||||
delayMs={index * ADMIN_MOTION.tileStaggerMs}
|
||||
/>
|
||||
))}
|
||||
</XStack>
|
||||
@@ -944,9 +931,8 @@ function KpiStrip({
|
||||
tasksEnabled: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation('management');
|
||||
const theme = useTheme();
|
||||
const text = String(theme.color12?.val ?? theme.color?.val ?? '#f8fafc');
|
||||
const muted = String(theme.gray11?.val ?? theme.gray?.val ?? '#cbd5e1');
|
||||
const { textStrong, muted } = useAdminTheme();
|
||||
const text = textStrong;
|
||||
if (!event) return null;
|
||||
|
||||
const kpis = [
|
||||
@@ -997,11 +983,8 @@ function KpiStrip({
|
||||
|
||||
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');
|
||||
const warningBg = String(theme.yellow3?.val ?? '#fff7ed');
|
||||
const warningBorder = String(theme.yellow6?.val ?? '#fed7aa');
|
||||
const warningText = String(theme.yellow11?.val ?? '#9a3412');
|
||||
const { textStrong, warningBg, warningBorder, warningText } = useAdminTheme();
|
||||
const text = textStrong;
|
||||
if (!event) return null;
|
||||
|
||||
const alerts: string[] = [];
|
||||
|
||||
Reference in New Issue
Block a user