diff --git a/apps/rebreak-native/app/devices.tsx b/apps/rebreak-native/app/devices.tsx index 4029bb3..45c3720 100644 --- a/apps/rebreak-native/app/devices.tsx +++ b/apps/rebreak-native/app/devices.tsx @@ -132,11 +132,14 @@ function MobileDeviceRow({ ); } + const deviceName = device.model ?? device.name ?? device.platform; + const footerText = `${formatLastSeen(device.lastSeenAt, t)} · ${t('settings.devices_since')} ${formatSince(device.createdAt)}`; + return ( - {device.name ?? device.model ?? device.platform} + {deviceName} {device.isCurrent ? ( - {device.model && device.name && !device.name.includes(device.model) ? ( - - {device.model} - - ) : null} - - - - - - {formatLastSeen(device.lastSeenAt, t)} - - - - - - {t('settings.devices_since')} {formatSince(device.createdAt)} - - - + + {footerText} + {!device.isCurrent ? ( @@ -277,7 +260,7 @@ function ProtectedDeviceRow({ - + - - - - {t('settings.devices_since')} {formatSince(device.createdAt)} - - - - {device.status === 'degraded' && ( - - {t('plan_limit.device_degraded_body')} - - )} + + {device.status === 'degraded' + ? t('plan_limit.device_degraded_body') + : `${t('settings.devices_since')} ${formatSince(device.createdAt)}`} + d.status !== 'revoked').length; + const totalRegistered = 1 + activeProtectedCount; const atDeviceLimit = isLegend && activeProtectedCount >= MAX_PROTECTED_DEVICES; const currentDevice = mobileDevices.find((d) => d.isCurrent); const subtitle = isLegend ? t('devices.subtitle_legend') : t('devices.subtitle_free'); + const counterText = isLegend + ? atDeviceLimit + ? t('devices.counter_limit', { max: TOTAL_DEVICE_SLOTS }) + : t('devices.counter_some', { + count: totalRegistered, + max: TOTAL_DEVICE_SLOTS, + remaining: TOTAL_DEVICE_SLOTS - totalRegistered, + }) + : null; + async function handleRemoveProtected(id: string) { try { const { manualRemovalRequired } = await removeProtected(id); @@ -457,18 +445,30 @@ export default function DevicesScreen() { }} showsVerticalScrollIndicator={false} > - {/* Subtitle */} - - {subtitle} - + {/* Subtitle + counter */} + + + {subtitle} + + {counterText ? ( + + {counterText} + + ) : null} + {/* Section 1: Dieses Gerät */} @@ -539,80 +539,57 @@ export default function DevicesScreen() { {/* CTA or Upgrade */} {isLegend ? ( - - {atDeviceLimit && ( - - - - {t('plan_limit.device_add_limit_hint', { max: MAX_PROTECTED_DEVICES })} - - - )} + atDeviceLimit ? ( { - if (atDeviceLimit) { - Alert.alert(t('plan_limit.device_add_limit_short'), t('plan_limit.device_add_limit_hint', { max: MAX_PROTECTED_DEVICES })); - return; - } - setAddMacVisible(true); + activeOpacity={1} + style={{ + backgroundColor: colors.surfaceElevated, + borderRadius: 14, + paddingVertical: 12, + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'center', + gap: 8, + opacity: 0.5, }} + > + + + {t('devices.add_device')} + + + ) : ( + { + if (event === 'mac') setAddMacVisible(true); + else if (event === 'windows') setAddWindowsVisible(true); + }} + shouldOpenOnLongPress={false} + > + - - - {t('devices.add_mac')} + + + {t('devices.add_device')} - - { - if (atDeviceLimit) { - Alert.alert(t('plan_limit.device_add_limit_short'), t('plan_limit.device_add_limit_hint', { max: MAX_PROTECTED_DEVICES })); - return; - } - setAddWindowsVisible(true); - }} - activeOpacity={0.7} - style={{ - borderRadius: 14, - paddingVertical: 14, - alignItems: 'center', - flexDirection: 'row', - justifyContent: 'center', - gap: 8, - backgroundColor: colors.surface, - borderWidth: 1, - borderColor: colors.border, - }} - > - - - {t('devices.add_windows_enabled')} - - - + + ) ) : ( diff --git a/apps/rebreak-native/components/devices/AddMacSheet.tsx b/apps/rebreak-native/components/devices/AddMacSheet.tsx index 225470c..77345e3 100644 --- a/apps/rebreak-native/components/devices/AddMacSheet.tsx +++ b/apps/rebreak-native/components/devices/AddMacSheet.tsx @@ -204,7 +204,7 @@ function Step1LabelContent({ style={{ backgroundColor: colors.brandOrange, borderRadius: 14, - paddingVertical: 16, + paddingVertical: 12, alignItems: 'center', opacity: enrolling ? 0.7 : 1, }} @@ -314,7 +314,7 @@ function Step2OnboardingContent({ style={{ backgroundColor: colors.brandOrange, borderRadius: 14, - paddingVertical: 16, + paddingVertical: 12, alignItems: 'center', flexDirection: 'row', justifyContent: 'center', @@ -430,7 +430,7 @@ function Step3SuccessContent({ style={{ backgroundColor: colors.brandOrange, borderRadius: 14, - paddingVertical: 16, + paddingVertical: 12, paddingHorizontal: 40, alignItems: 'center', alignSelf: 'stretch', diff --git a/apps/rebreak-native/components/devices/AddWindowsSheet.tsx b/apps/rebreak-native/components/devices/AddWindowsSheet.tsx index 1c8df4d..2369cc9 100644 --- a/apps/rebreak-native/components/devices/AddWindowsSheet.tsx +++ b/apps/rebreak-native/components/devices/AddWindowsSheet.tsx @@ -212,7 +212,7 @@ function WindowsStep1LabelContent({ style={{ backgroundColor: colors.brandOrange, borderRadius: 14, - paddingVertical: 16, + paddingVertical: 12, alignItems: 'center', opacity: enrolling ? 0.7 : 1, }} @@ -326,7 +326,7 @@ function WindowsStep2OnboardingContent({ style={{ backgroundColor: colors.brandOrange, borderRadius: 14, - paddingVertical: 16, + paddingVertical: 12, alignItems: 'center', flexDirection: 'row', justifyContent: 'center', @@ -348,7 +348,7 @@ function WindowsStep2OnboardingContent({ borderWidth: 1.5, borderColor: colors.brandOrange, borderRadius: 14, - paddingVertical: 14, + paddingVertical: 12, alignItems: 'center', opacity: confirming ? 0.7 : 1, }} @@ -434,7 +434,7 @@ function WindowsStep3SuccessContent({ style={{ backgroundColor: colors.brandOrange, borderRadius: 14, - paddingVertical: 16, + paddingVertical: 12, paddingHorizontal: 40, alignItems: 'center', alignSelf: 'stretch', diff --git a/apps/rebreak-native/locales/de.json b/apps/rebreak-native/locales/de.json index bae6dec..729630c 100644 --- a/apps/rebreak-native/locales/de.json +++ b/apps/rebreak-native/locales/de.json @@ -889,6 +889,9 @@ "success_body": "Du kannst weitere Geräte hinzufügen wenn du willst.", "remove_warning_title": "Profile manuell entfernen", "remove_warning_body": "Wir können das Profile nicht aus der Ferne löschen. Auf dem Mac: Systemeinstellungen → Profile → ReBreak → Entfernen (Admin-Passwort nötig).", + "add_device": "+ neues Gerät hinzufügen", + "counter_some": "{{count}} von {{max}} Geräten · noch {{remaining}} frei", + "counter_limit": "Maximum erreicht — {{max}} von {{max}} Geräten", "add_windows_enabled": "Windows-PC hinzufügen", "windows_label_question": "Wie soll der Windows-PC heißen?", "windows_label_default": "Windows-PC", diff --git a/apps/rebreak-native/locales/en.json b/apps/rebreak-native/locales/en.json index c792920..3eb50cb 100644 --- a/apps/rebreak-native/locales/en.json +++ b/apps/rebreak-native/locales/en.json @@ -889,6 +889,9 @@ "success_body": "You can add more devices whenever you like.", "remove_warning_title": "Remove profile manually", "remove_warning_body": "We can't delete the profile remotely. On the Mac: System Settings → Profiles → ReBreak → Remove (admin password required).", + "add_device": "+ add new device", + "counter_some": "{{count}} of {{max}} devices · {{remaining}} more available", + "counter_limit": "Maximum reached — {{max}} of {{max}} devices", "add_windows_enabled": "Add Windows PC", "windows_label_question": "What should this Windows PC be called?", "windows_label_default": "Windows PC", diff --git a/apps/rebreak-native/locales/fr.json b/apps/rebreak-native/locales/fr.json index e2a4381..d8afce2 100644 --- a/apps/rebreak-native/locales/fr.json +++ b/apps/rebreak-native/locales/fr.json @@ -886,6 +886,9 @@ "success_body": "Vous pouvez ajouter d'autres appareils quand vous le souhaitez.", "remove_warning_title": "Supprimer le profil manuellement", "remove_warning_body": "Nous ne pouvons pas supprimer le profil à distance. Sur le Mac : Réglages système → Profils → ReBreak → Supprimer (mot de passe administrateur requis).", + "add_device": "+ ajouter un appareil", + "counter_some": "{{count}} sur {{max}} appareils · encore {{remaining}} disponible", + "counter_limit": "Maximum atteint — {{max}} sur {{max}} appareils", "add_windows_enabled": "Ajouter un PC Windows", "windows_label_question": "Comment appeler ce PC Windows ?", "windows_label_default": "PC Windows",