admin mobile: improve small-screen readability across checklist, tabs, badges, and headers
This commit is contained in:
@@ -980,8 +980,8 @@ function PackageCard({
|
||||
backgroundColor={isActive ? accentSoft : undefined}
|
||||
gap="$2"
|
||||
>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$md" fontWeight="800" color={textStrong}>
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<Text fontSize="$md" fontWeight="800" color={textStrong} flex={1} minWidth={0}>
|
||||
{pkg.package_name ?? t('mobileBilling.packageFallback', 'Package')}
|
||||
</Text>
|
||||
{label ? <PillBadge tone="success">{label}</PillBadge> : null}
|
||||
@@ -1262,8 +1262,8 @@ function AddonRow({
|
||||
|
||||
return (
|
||||
<MobileCard borderColor={border} padding="$3" gap="$1.5">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong} flex={1} minWidth={0}>
|
||||
{addon.label ?? addon.addon_key}
|
||||
</Text>
|
||||
<PillBadge tone={status.tone}>{status.text}</PillBadge>
|
||||
@@ -1271,11 +1271,11 @@ function AddonRow({
|
||||
{!hideEventLink && eventName ? (
|
||||
eventPath ? (
|
||||
<Pressable onPress={() => navigate(eventPath)}>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$xs" color={textStrong} fontWeight="600">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<Text fontSize="$xs" color={textStrong} fontWeight="600" flex={1} minWidth={0}>
|
||||
{eventName}
|
||||
</Text>
|
||||
<Text fontSize="$xs" color={primary} fontWeight="700">
|
||||
<Text fontSize="$xs" color={primary} fontWeight="700" flexShrink={0}>
|
||||
{t('mobileBilling.openEvent', 'Open event')}
|
||||
</Text>
|
||||
</XStack>
|
||||
@@ -1316,8 +1316,8 @@ function EventAddonRow({ addon }: { addon: EventAddonSummary }) {
|
||||
|
||||
return (
|
||||
<MobileCard borderColor={border} padding="$3" gap="$1.5">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong} flex={1} minWidth={0}>
|
||||
{addon.label ?? addon.key}
|
||||
</Text>
|
||||
<PillBadge tone={status.tone}>{status.text}</PillBadge>
|
||||
|
||||
@@ -629,9 +629,9 @@ function LifecycleHero({
|
||||
paddingHorizontal="$3"
|
||||
onPress={() => navigate(adminPath(nextStep.targetPath))}
|
||||
title={
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<XStack alignItems="flex-start" gap="$2" flex={1} minWidth={0}>
|
||||
<Circle size={18} color={theme.primary} strokeWidth={2.5} />
|
||||
<Text fontSize="$sm" fontWeight="700" color={theme.textStrong}>
|
||||
<Text fontSize="$sm" fontWeight="700" color={theme.textStrong} flexShrink={1}>
|
||||
{nextStep.label}
|
||||
</Text>
|
||||
</XStack>
|
||||
@@ -644,8 +644,17 @@ function LifecycleHero({
|
||||
) : undefined
|
||||
}
|
||||
iconAfter={
|
||||
<XStack alignItems="center" gap="$1">
|
||||
<PillBadge tone="success">{nextStep.ctaLabel}</PillBadge>
|
||||
<XStack alignItems="center" gap="$1" maxWidth="52%" flexShrink={1}>
|
||||
<Text
|
||||
fontSize="$xs"
|
||||
fontWeight="700"
|
||||
color={theme.primary}
|
||||
textAlign="right"
|
||||
numberOfLines={2}
|
||||
flexShrink={1}
|
||||
>
|
||||
{nextStep.ctaLabel}
|
||||
</Text>
|
||||
<ChevronRight size={16} color={theme.muted} />
|
||||
</XStack>
|
||||
}
|
||||
|
||||
@@ -335,11 +335,11 @@ export default function MobileEventGuestNotificationsPage() {
|
||||
<YStack gap="$2">
|
||||
{history.map((item) => (
|
||||
<MobileCard key={item.id} gap="$2" borderColor={border}>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$sm" fontWeight="800" color={textStrong}>
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<Text fontSize="$sm" fontWeight="800" color={textStrong} flex={1} minWidth={0}>
|
||||
{item.title || t('guestMessages.history.untitled', 'Untitled')}
|
||||
</Text>
|
||||
<XStack gap="$1.5" alignItems="center">
|
||||
<XStack gap="$1.5" alignItems="center" flexWrap="wrap" justifyContent="flex-end">
|
||||
<PillBadge tone={item.status === 'active' ? 'success' : 'muted'}>
|
||||
{t(`guestMessages.status.${item.status}`, item.status)}
|
||||
</PillBadge>
|
||||
@@ -353,8 +353,8 @@ export default function MobileEventGuestNotificationsPage() {
|
||||
<Text fontSize="$sm" color={text}>
|
||||
{item.body ?? t('guestMessages.history.noBody', 'No body provided.')}
|
||||
</Text>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<XStack gap="$1.5" alignItems="center">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<XStack gap="$1.5" alignItems="center" flexWrap="wrap" flex={1} minWidth={0}>
|
||||
<PillBadge tone="muted">{t(`guestMessages.type.${item.type}`, item.type)}</PillBadge>
|
||||
{item.target_identifier ? (
|
||||
<PillBadge tone="muted">
|
||||
@@ -376,7 +376,7 @@ export default function MobileEventGuestNotificationsPage() {
|
||||
</PillBadge>
|
||||
)}
|
||||
</XStack>
|
||||
<Text fontSize="$xs" color={mutedText}>
|
||||
<Text fontSize="$xs" color={mutedText} flexShrink={0}>
|
||||
{formatGuestMessageDate(item.created_at, locale)}
|
||||
</Text>
|
||||
</XStack>
|
||||
|
||||
@@ -358,15 +358,15 @@ export default function MobileEventMembersPage() {
|
||||
const statusInfo = resolveStatus(member.status);
|
||||
return (
|
||||
<MobileCard key={member.id} padding="$3" borderColor={border}>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2">
|
||||
<YStack gap="$1" flex={1} minWidth={0}>
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong} numberOfLines={2}>
|
||||
{member.name || member.email || t('events.members.fallbackName', 'Guest')}
|
||||
</Text>
|
||||
<Text fontSize="$xs" color={muted}>
|
||||
<Text fontSize="$xs" color={muted} numberOfLines={2}>
|
||||
{member.email ?? ''}
|
||||
</Text>
|
||||
<XStack gap="$1.5" alignItems="center">
|
||||
<XStack gap="$1.5" alignItems="center" flexWrap="wrap">
|
||||
<PillBadge tone={statusInfo.tone}>
|
||||
{statusInfo.label}
|
||||
</PillBadge>
|
||||
|
||||
@@ -200,60 +200,72 @@ export default function MobileEventRecapPage() {
|
||||
orientation="horizontal"
|
||||
flexDirection="column"
|
||||
>
|
||||
<Tabs.List gap="$2">
|
||||
<Tabs.List gap="$1" flexWrap="wrap">
|
||||
<Tabs.Tab
|
||||
value="overview"
|
||||
flex={1}
|
||||
paddingVertical="$2.5"
|
||||
paddingHorizontal="$3"
|
||||
flexGrow={1}
|
||||
flexShrink={1}
|
||||
flexBasis="calc(33.333% - 4px)"
|
||||
minWidth={108}
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$2"
|
||||
borderRadius="$4"
|
||||
hoverStyle={{ backgroundColor: '$backgroundHover' }}
|
||||
pressStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
activeStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
>
|
||||
<Text
|
||||
fontSize="$sm"
|
||||
fontSize="$xs"
|
||||
fontWeight={activeTab === 'overview' ? '700' : '600'}
|
||||
color={activeTab === 'overview' ? text : muted}
|
||||
textAlign="center"
|
||||
numberOfLines={2}
|
||||
>
|
||||
{t('events.recap.tabs.overview', 'Overview')}
|
||||
</Text>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
value="engagement"
|
||||
flex={1}
|
||||
paddingVertical="$2.5"
|
||||
paddingHorizontal="$3"
|
||||
flexGrow={1}
|
||||
flexShrink={1}
|
||||
flexBasis="calc(33.333% - 4px)"
|
||||
minWidth={108}
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$2"
|
||||
borderRadius="$4"
|
||||
hoverStyle={{ backgroundColor: '$backgroundHover' }}
|
||||
pressStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
activeStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
>
|
||||
<Text
|
||||
fontSize="$sm"
|
||||
fontSize="$xs"
|
||||
fontWeight={activeTab === 'engagement' ? '700' : '600'}
|
||||
color={activeTab === 'engagement' ? text : muted}
|
||||
textAlign="center"
|
||||
numberOfLines={2}
|
||||
>
|
||||
{t('events.recap.tabs.engagement', 'Engagement')}
|
||||
</Text>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
value="compliance"
|
||||
flex={1}
|
||||
paddingVertical="$2.5"
|
||||
paddingHorizontal="$3"
|
||||
flexGrow={1}
|
||||
flexShrink={1}
|
||||
flexBasis="calc(33.333% - 4px)"
|
||||
minWidth={108}
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$2"
|
||||
borderRadius="$4"
|
||||
hoverStyle={{ backgroundColor: '$backgroundHover' }}
|
||||
pressStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
activeStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
>
|
||||
<Text
|
||||
fontSize="$sm"
|
||||
fontSize="$xs"
|
||||
fontWeight={activeTab === 'compliance' ? '700' : '600'}
|
||||
color={activeTab === 'compliance' ? text : muted}
|
||||
textAlign="center"
|
||||
numberOfLines={2}
|
||||
>
|
||||
{t('events.recap.tabs.compliance', 'Compliance')}
|
||||
</Text>
|
||||
@@ -263,8 +275,8 @@ export default function MobileEventRecapPage() {
|
||||
<Tabs.Content value="overview" paddingTop="$2">
|
||||
<YStack gap="$4">
|
||||
<MobileCard gap="$3">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<YStack gap="$1" flex={1} minWidth={0}>
|
||||
<Text fontSize="$xl" fontWeight="800" color={textStrong}>
|
||||
{t('events.recap.completedTitle', 'Event abgeschlossen')}
|
||||
</Text>
|
||||
|
||||
@@ -1176,31 +1176,45 @@ export default function MobileEventTasksPage() {
|
||||
borderRadius={16}
|
||||
borderWidth={1}
|
||||
borderColor={border}
|
||||
overflow="hidden"
|
||||
gap="$0"
|
||||
overflow="visible"
|
||||
gap="$1"
|
||||
flexWrap="wrap"
|
||||
padding="$1"
|
||||
>
|
||||
{[
|
||||
{ value: 'assigned', label: t('events.tasks.tabs.tasks', 'Tasks') },
|
||||
{ value: 'library', label: t('events.tasks.tabs.library', 'Task Library') },
|
||||
{ value: 'emotions', label: t('events.tasks.tabs.emotions', 'Emotions') },
|
||||
{ value: 'collections', label: t('events.tasks.tabs.collections', 'Collections') },
|
||||
].map((tab, index, arr) => {
|
||||
].map((tab) => {
|
||||
const isActive = activeTab === tab.value;
|
||||
return (
|
||||
<Tabs.Tab
|
||||
key={tab.value}
|
||||
value={tab.value}
|
||||
flex={1}
|
||||
paddingVertical="$2.5"
|
||||
flexGrow={1}
|
||||
flexShrink={1}
|
||||
flexBasis="calc(50% - 4px)"
|
||||
minWidth={132}
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$2"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
borderRightWidth={index === arr.length - 1 ? 0 : 1}
|
||||
borderRightColor={border}
|
||||
borderWidth={1}
|
||||
borderColor={isActive ? withAlpha(primary, 0.45) : border}
|
||||
borderRadius={12}
|
||||
backgroundColor={isActive ? withAlpha(primary, 0.12) : surface}
|
||||
hoverStyle={{ backgroundColor: '$backgroundHover' }}
|
||||
pressStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
activeStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
>
|
||||
<Text fontSize="$sm" fontWeight={isActive ? '700' : '600'} color={isActive ? text : muted}>
|
||||
<Text
|
||||
fontSize="$xs"
|
||||
fontWeight={isActive ? '700' : '600'}
|
||||
color={isActive ? text : muted}
|
||||
numberOfLines={2}
|
||||
textAlign="center"
|
||||
>
|
||||
{tab.label}
|
||||
</Text>
|
||||
</Tabs.Tab>
|
||||
@@ -1232,6 +1246,7 @@ export default function MobileEventTasksPage() {
|
||||
<XStack
|
||||
alignItems="center"
|
||||
gap="$1.5"
|
||||
flexShrink={1}
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$3"
|
||||
borderRadius={14}
|
||||
@@ -1239,14 +1254,16 @@ export default function MobileEventTasksPage() {
|
||||
borderColor={border}
|
||||
backgroundColor={surface}
|
||||
>
|
||||
<Text fontSize={11} fontWeight="700" color={text}>
|
||||
{t('events.tasks.emotionFilterShort', 'Emotion')}
|
||||
</Text>
|
||||
<Text fontSize={11} color={muted}>
|
||||
{emotionFilter
|
||||
? emotions.find((e) => String(e.id) === emotionFilter)?.name ?? t('events.tasks.customEmotion', 'Custom emotion')
|
||||
: t('events.tasks.allEmotions', 'All')}
|
||||
</Text>
|
||||
<YStack flexShrink={1} minWidth={0} maxWidth={128}>
|
||||
<Text fontSize={11} fontWeight="700" color={text} numberOfLines={1}>
|
||||
{t('events.tasks.emotionFilterShort', 'Emotion')}
|
||||
</Text>
|
||||
<Text fontSize={11} color={muted} numberOfLines={1}>
|
||||
{emotionFilter
|
||||
? emotions.find((e) => String(e.id) === emotionFilter)?.name ?? t('events.tasks.customEmotion', 'Custom emotion')
|
||||
: t('events.tasks.allEmotions', 'All')}
|
||||
</Text>
|
||||
</YStack>
|
||||
<ChevronDown size={14} color={muted} />
|
||||
</XStack>
|
||||
</Pressable>
|
||||
|
||||
@@ -449,11 +449,11 @@ function EventListItem({
|
||||
const stats = buildEventListStats(event);
|
||||
return (
|
||||
<YStack gap="$1.5">
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$2">
|
||||
<Text fontSize="$md" fontWeight="800" color={text}>
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<Text fontSize="$md" fontWeight="800" color={text} flex={1} minWidth={0}>
|
||||
{renderName(event.name, t)}
|
||||
</Text>
|
||||
<XStack alignItems="center" gap="$1.5">
|
||||
<XStack alignItems="center" gap="$1.5" flexWrap="wrap" justifyContent="flex-end">
|
||||
<PillBadge tone={statusTone}>{statusLabel}</PillBadge>
|
||||
{onEdit ? (
|
||||
<Pressable onPress={() => onEdit(event.slug)}>
|
||||
|
||||
@@ -239,10 +239,10 @@ function PackageShopCard({
|
||||
backgroundColor={isActive ? '$green1' : undefined}
|
||||
style={{ opacity: isSubdued ? 0.6 : 1 }}
|
||||
>
|
||||
<XStack justifyContent="space-between" alignItems="flex-start">
|
||||
<YStack gap="$1">
|
||||
<XStack gap="$2" alignItems="center">
|
||||
<Text fontSize="$lg" fontWeight="800" color={textStrong}>
|
||||
<XStack justifyContent="space-between" alignItems="flex-start" gap="$2" flexWrap="wrap">
|
||||
<YStack gap="$1" flex={1} minWidth={0}>
|
||||
<XStack gap="$2" alignItems="center" flexWrap="wrap">
|
||||
<Text fontSize="$lg" fontWeight="800" color={textStrong} flexShrink={1}>
|
||||
{pkg.name}
|
||||
</Text>
|
||||
{isRecommended && <PillBadge tone="warning">{t('shop.badges.recommended', 'Recommended')}</PillBadge>}
|
||||
@@ -255,12 +255,12 @@ function PackageShopCard({
|
||||
{!isResellerCatalog && isActive ? <PillBadge tone="success">{t('shop.badges.active', 'Active')}</PillBadge> : null}
|
||||
</XStack>
|
||||
|
||||
<XStack gap="$2" alignItems="center">
|
||||
<XStack gap="$2" alignItems="center" flexWrap="wrap">
|
||||
<Text fontSize="$md" color={primary} fontWeight="700">
|
||||
{new Intl.NumberFormat(undefined, { style: 'currency', currency: 'EUR' }).format(pkg.price)}
|
||||
</Text>
|
||||
{statusLabel && (
|
||||
<Text fontSize="$xs" color={muted} fontWeight="600">
|
||||
<Text fontSize="$xs" color={muted} fontWeight="600" flexShrink={1}>
|
||||
• {statusLabel}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -583,41 +583,49 @@ export default function MobileProfileAccountPage() {
|
||||
orientation="horizontal"
|
||||
flexDirection="column"
|
||||
>
|
||||
<Tabs.List gap="$2">
|
||||
<Tabs.List gap="$1" flexWrap="wrap">
|
||||
<Tabs.Tab
|
||||
value="account"
|
||||
flex={1}
|
||||
paddingVertical="$2.5"
|
||||
paddingHorizontal="$3"
|
||||
flexGrow={1}
|
||||
flexShrink={1}
|
||||
flexBasis="calc(50% - 4px)"
|
||||
minWidth={132}
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$2"
|
||||
borderRadius="$4"
|
||||
hoverStyle={{ backgroundColor: '$backgroundHover' }}
|
||||
pressStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
activeStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
>
|
||||
<Text
|
||||
fontSize="$sm"
|
||||
fontSize="$xs"
|
||||
fontWeight={activeTab === 'account' ? '700' : '600'}
|
||||
color={activeTab === 'account' ? text : muted}
|
||||
textAlign="center"
|
||||
numberOfLines={2}
|
||||
>
|
||||
{t('profile.tabs.account', 'Account')}
|
||||
</Text>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
value="branding"
|
||||
flex={1}
|
||||
paddingVertical="$2.5"
|
||||
paddingHorizontal="$3"
|
||||
flexGrow={1}
|
||||
flexShrink={1}
|
||||
flexBasis="calc(50% - 4px)"
|
||||
minWidth={132}
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$2"
|
||||
borderRadius="$4"
|
||||
hoverStyle={{ backgroundColor: '$backgroundHover' }}
|
||||
pressStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
activeStyle={{ backgroundColor: '$backgroundPress' }}
|
||||
>
|
||||
<Text
|
||||
fontSize="$sm"
|
||||
fontSize="$xs"
|
||||
fontWeight={activeTab === 'branding' ? '700' : '600'}
|
||||
color={activeTab === 'branding' ? text : muted}
|
||||
textAlign="center"
|
||||
numberOfLines={2}
|
||||
>
|
||||
{t('profile.tabs.branding', 'Standard-Branding')}
|
||||
</Text>
|
||||
|
||||
@@ -338,7 +338,7 @@ export default function MobileSettingsPage() {
|
||||
</Text>
|
||||
) : (
|
||||
<YStack gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$2">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<YStack flex={1} gap="$1">
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{t('mobileSettings.deviceStatus.notifications.label', 'Notifications')}
|
||||
@@ -351,7 +351,7 @@ export default function MobileSettingsPage() {
|
||||
{permissionLabel(devicePermissions.notifications)}
|
||||
</PillBadge>
|
||||
</XStack>
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$2">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<YStack flex={1} gap="$1">
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{t('mobileSettings.deviceStatus.camera.label', 'Camera')}
|
||||
@@ -364,7 +364,7 @@ export default function MobileSettingsPage() {
|
||||
{permissionLabel(devicePermissions.camera)}
|
||||
</PillBadge>
|
||||
</XStack>
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$2">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<YStack flex={1} gap="$1">
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{t('mobileSettings.deviceStatus.storage.label', 'Offline storage')}
|
||||
@@ -377,7 +377,7 @@ export default function MobileSettingsPage() {
|
||||
{storageLabel(devicePermissions.storage)}
|
||||
</PillBadge>
|
||||
</XStack>
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$2">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<YStack flex={1} gap="$1">
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{t('mobileSettings.deviceStatus.connection.label', 'Connection')}
|
||||
|
||||
@@ -39,19 +39,21 @@ export function SetupChecklist({
|
||||
<YStack>
|
||||
<Pressable onPress={() => setCollapsed(!collapsed)}>
|
||||
<YStack padding="$3" paddingVertical="$2.5" gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<XStack alignItems="flex-start" justifyContent="space-between" gap="$2" flexWrap="wrap">
|
||||
<XStack alignItems="center" gap="$2" flex={1} minWidth={0} flexWrap="wrap">
|
||||
<Text fontSize="$xs" fontWeight="700" color={theme.muted} textTransform="uppercase" letterSpacing={1}>
|
||||
{title}
|
||||
</Text>
|
||||
{isAllComplete ? (
|
||||
<CheckCircle2 size={14} color={theme.successText} />
|
||||
) : (
|
||||
<PillBadge tone="warning">{t('readiness.pending', 'Noch offen')}</PillBadge>
|
||||
<XStack flexShrink={0}>
|
||||
<PillBadge tone="warning">{t('readiness.pending', 'Noch offen')}</PillBadge>
|
||||
</XStack>
|
||||
)}
|
||||
</XStack>
|
||||
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<XStack alignItems="center" justifyContent="flex-end" gap="$2" flexShrink={0}>
|
||||
<Text fontSize="$xs" color={theme.muted} fontWeight="600">
|
||||
{completedCount}/{steps.length}
|
||||
</Text>
|
||||
@@ -89,7 +91,7 @@ export function SetupChecklist({
|
||||
backgroundColor={isNext ? theme.surfaceMuted : 'transparent'}
|
||||
onPress={() => navigate(adminPath(step.targetPath))}
|
||||
title={
|
||||
<XStack alignItems="center" gap="$2.5">
|
||||
<XStack alignItems="flex-start" gap="$2.5" flex={1} minWidth={0}>
|
||||
{step.isComplete ? (
|
||||
<CheckCircle2 size={18} color={theme.successText} />
|
||||
) : isNext ? (
|
||||
@@ -102,6 +104,7 @@ export function SetupChecklist({
|
||||
fontWeight={isNext ? '700' : '500'}
|
||||
color={step.isComplete ? theme.muted : theme.textStrong}
|
||||
textDecorationLine={step.isComplete ? 'line-through' : 'none'}
|
||||
flexShrink={1}
|
||||
>
|
||||
{step.label}
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user