diff --git a/apps/rebreak-native/app/devices.tsx b/apps/rebreak-native/app/devices.tsx index 310cec4..7ca1ace 100644 --- a/apps/rebreak-native/app/devices.tsx +++ b/apps/rebreak-native/app/devices.tsx @@ -21,6 +21,7 @@ import { useUserPlan } from '../hooks/useUserPlan'; import { AppHeader } from '../components/AppHeader'; import { AddMacSheet } from '../components/devices/AddMacSheet'; import { AddWindowsSheet } from '../components/devices/AddWindowsSheet'; +import { DeviceProgressBar } from '../components/devices/DeviceProgressBar'; // ─── Helpers ───────────────────────────────────────────────────────────────── @@ -411,16 +412,6 @@ export default function DevicesScreen() { 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); @@ -446,8 +437,8 @@ export default function DevicesScreen() { }} showsVerticalScrollIndicator={false} > - {/* Subtitle + counter */} - + {/* Subtitle + progress */} + {subtitle} - {counterText ? ( - - {counterText} - + {isLegend ? ( + ) : null} diff --git a/apps/rebreak-native/components/devices/DeviceProgressBar.tsx b/apps/rebreak-native/components/devices/DeviceProgressBar.tsx new file mode 100644 index 0000000..efa587e --- /dev/null +++ b/apps/rebreak-native/components/devices/DeviceProgressBar.tsx @@ -0,0 +1,76 @@ +import { useEffect, useRef } from 'react'; +import { Animated, Text, View } from 'react-native'; +import { useTranslation } from 'react-i18next'; +import { useColors } from '../../lib/theme'; + +interface DeviceProgressBarProps { + count: number; + max: number; + atLimit: boolean; +} + +export function DeviceProgressBar({ count, max, atLimit }: DeviceProgressBarProps) { + const { t } = useTranslation(); + const colors = useColors(); + const fillAnim = useRef(new Animated.Value(0)).current; + + const ratio = max > 0 ? Math.min(count / max, 1) : 0; + + useEffect(() => { + Animated.timing(fillAnim, { + toValue: ratio, + duration: 380, + useNativeDriver: false, + }).start(); + }, [ratio]); + + const fillColor = atLimit ? colors.brandOrange : colors.success; + + return ( + + + + {atLimit + ? t('devices.progress_at_limit') + : t('devices.progress_label', { count, max })} + + + {count}/{max} + + + + + + + + ); +} diff --git a/apps/rebreak-native/locales/de.json b/apps/rebreak-native/locales/de.json index 392cafd..4ebfb64 100644 --- a/apps/rebreak-native/locales/de.json +++ b/apps/rebreak-native/locales/de.json @@ -890,8 +890,8 @@ "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", + "progress_label": "%{count} von %{max} Geräten", + "progress_at_limit": "Maximum erreicht", "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 fdf8450..b0c5346 100644 --- a/apps/rebreak-native/locales/en.json +++ b/apps/rebreak-native/locales/en.json @@ -890,8 +890,8 @@ "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", + "progress_label": "%{count} of %{max} devices", + "progress_at_limit": "Maximum reached", "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 f890bc5..ce0f214 100644 --- a/apps/rebreak-native/locales/fr.json +++ b/apps/rebreak-native/locales/fr.json @@ -887,8 +887,8 @@ "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", + "progress_label": "%{count} sur %{max} appareils", + "progress_at_limit": "Maximum atteint", "add_windows_enabled": "Ajouter un PC Windows", "windows_label_question": "Comment appeler ce PC Windows ?", "windows_label_default": "PC Windows",