diff --git a/apps/rebreak-native/locales/de.json b/apps/rebreak-native/locales/de.json index eb1b79f..5e27ddc 100644 --- a/apps/rebreak-native/locales/de.json +++ b/apps/rebreak-native/locales/de.json @@ -76,7 +76,13 @@ "toLogin": "Zur Anmeldung", "oauthFailed": "Anmeldung fehlgeschlagen", "loginFailed": "Anmeldung fehlgeschlagen", - "registerFailed": "Registrierung fehlgeschlagen" + "registerFailed": "Registrierung fehlgeschlagen", + "device_locked_headline": "Dieses Gerät ist gesperrt", + "device_locked_body": "Du hast versucht, dich mit diesem Gerät anzumelden. Es ist aber an einen anderen Rebreak-Account gebunden. Diese Sperre schützt dich davor, im Drang-Moment dein eigenes Schutz-Setup zu umgehen.", + "device_locked_countdown": "Freigabe läuft — noch %{remaining}", + "device_locked_email_hint": "Wenn du dein Original-Konto nicht mehr kennst: Schau in deinem E-Mail-Postfach nach 'Rebreak Gerät gesperrt' — wir haben dir eine Mail geschickt.", + "device_locked_use_original": "Mit Original-Account anmelden", + "device_locked_back": "Zurück zur Anmeldung" }, "landing": { "appName": "Rebreak", @@ -926,7 +932,16 @@ "windows_download_button": "Datei auf Windows-PC herunterladen", "windows_success_title": "Windows-PC geschützt!", "windows_success_body": "Du kannst weitere Geräte hinzufügen wenn du willst.", - "windows_remove_warning_body": "Wir können die Registrierung nicht aus der Ferne löschen. Auf dem PC: Regedit → HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DoHSvc → Schlüssel entfernen." + "windows_remove_warning_body": "Wir können die Registrierung nicht aus der Ferne löschen. Auf dem PC: Regedit → HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DoHSvc → Schlüssel entfernen.", + "bound_badge": "Gebunden", + "release_request_title": "Gerät freigeben?", + "release_request_body": "Das Gerät wird nach 24 Stunden freigegeben. Du kannst die Freigabe vorher jederzeit widerrufen.", + "release_request_confirm": "Freigabe starten", + "release_countdown": "Freigabe in %{remaining}", + "release_cancel": "Freigabe abbrechen", + "release_cancel_confirm": "Freigabe wirklich abbrechen?", + "release_cancel_body": "Das Gerät bleibt weiterhin an deinen Account gebunden.", + "release_cancel_cta": "Ja, abbrechen" }, "plan": { "change": { diff --git a/apps/rebreak-native/locales/en.json b/apps/rebreak-native/locales/en.json index ce7fd3b..72e1522 100644 --- a/apps/rebreak-native/locales/en.json +++ b/apps/rebreak-native/locales/en.json @@ -76,7 +76,13 @@ "toLogin": "Back to sign in", "oauthFailed": "Sign in failed", "loginFailed": "Sign in failed", - "registerFailed": "Registration failed" + "registerFailed": "Registration failed", + "device_locked_headline": "This device is locked", + "device_locked_body": "You tried to sign in on this device. It is bound to a different Rebreak account. This lock protects you from bypassing your own protection setup in a moment of urge.", + "device_locked_countdown": "Release in progress — %{remaining} left", + "device_locked_email_hint": "If you no longer know your original account: check your email inbox for 'Rebreak device locked' — we sent you a message.", + "device_locked_use_original": "Sign in with original account", + "device_locked_back": "Back to sign in" }, "landing": { "appName": "Rebreak", @@ -926,7 +932,16 @@ "windows_download_button": "Download file to Windows PC", "windows_success_title": "Windows PC protected!", "windows_success_body": "You can add more devices whenever you like.", - "windows_remove_warning_body": "We can't delete the registry entry remotely. On the PC: Regedit → HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DoHSvc → remove the key." + "windows_remove_warning_body": "We can't delete the registry entry remotely. On the PC: Regedit → HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DoHSvc → remove the key.", + "bound_badge": "Bound", + "release_request_title": "Release device?", + "release_request_body": "The device will be released after 24 hours. You can cancel the release at any time before that.", + "release_request_confirm": "Start release", + "release_countdown": "Release in %{remaining}", + "release_cancel": "Cancel release", + "release_cancel_confirm": "Really cancel the release?", + "release_cancel_body": "The device will remain bound to your account.", + "release_cancel_cta": "Yes, cancel" }, "plan": { "change": { diff --git a/apps/rebreak-native/locales/fr.json b/apps/rebreak-native/locales/fr.json index 5077de4..b83e2ce 100644 --- a/apps/rebreak-native/locales/fr.json +++ b/apps/rebreak-native/locales/fr.json @@ -76,7 +76,13 @@ "toLogin": "Retour à la connexion", "oauthFailed": "Connexion échouée", "loginFailed": "Connexion échouée", - "registerFailed": "Inscription échouée" + "registerFailed": "Inscription échouée", + "device_locked_headline": "Cet appareil est verrouillé", + "device_locked_body": "Vous avez tenté de vous connecter sur cet appareil. Il est lié à un autre compte Rebreak. Ce verrou vous protège contre le contournement de votre propre configuration de protection.", + "device_locked_countdown": "Libération en cours — encore %{remaining}", + "device_locked_email_hint": "Si vous ne connaissez plus votre compte d'origine : vérifiez votre boîte e-mail pour 'Rebreak appareil verrouillé' — nous vous avons envoyé un message.", + "device_locked_use_original": "Se connecter avec le compte d'origine", + "device_locked_back": "Retour à la connexion" }, "landing": { "appName": "Rebreak", @@ -923,7 +929,16 @@ "windows_download_button": "Télécharger le fichier sur le PC Windows", "windows_success_title": "PC Windows protégé !", "windows_success_body": "Vous pouvez ajouter d'autres appareils quand vous le souhaitez.", - "windows_remove_warning_body": "Nous ne pouvons pas supprimer l'entrée de registre à distance. Sur le PC : Regedit → HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DoHSvc → supprimer la clé." + "windows_remove_warning_body": "Nous ne pouvons pas supprimer l'entrée de registre à distance. Sur le PC : Regedit → HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DoHSvc → supprimer la clé.", + "bound_badge": "Lié", + "release_request_title": "Libérer l'appareil ?", + "release_request_body": "L'appareil sera libéré après 24 heures. Vous pouvez annuler la libération à tout moment avant cela.", + "release_request_confirm": "Démarrer la libération", + "release_countdown": "Libération dans %{remaining}", + "release_cancel": "Annuler la libération", + "release_cancel_confirm": "Vraiment annuler la libération ?", + "release_cancel_body": "L'appareil restera lié à votre compte.", + "release_cancel_cta": "Oui, annuler" }, "plan": { "change": { diff --git a/apps/rebreak-native/stores/devices.ts b/apps/rebreak-native/stores/devices.ts index e230568..58425cf 100644 --- a/apps/rebreak-native/stores/devices.ts +++ b/apps/rebreak-native/stores/devices.ts @@ -11,6 +11,8 @@ export interface UserDevice { lastSeenAt: string; createdAt: string; isCurrent?: boolean; + boundToPlan: 'free' | 'pro' | 'legend' | 'standard' | 'premium' | null; + releaseRequestedAt: string | null; } type DevicesState = { @@ -22,6 +24,8 @@ type DevicesState = { ensureRegistered: () => Promise; loadDevices: () => Promise; removeDevice: (id: string) => Promise; + requestRelease: (id: string) => Promise; + cancelRelease: (id: string) => Promise; }; export const useDevicesStore = create((set) => ({ @@ -67,4 +71,23 @@ export const useDevicesStore = create((set) => ({ await apiFetch(`/api/devices/${id}`, { method: 'DELETE' }); set((s) => ({ devices: s.devices.filter((d) => d.id !== id) })); }, + + requestRelease: async (id: string) => { + await apiFetch(`/api/devices/${id}/request-release`, { method: 'POST' }); + const now = new Date().toISOString(); + set((s) => ({ + devices: s.devices.map((d) => + d.id === id ? { ...d, releaseRequestedAt: now } : d + ), + })); + }, + + cancelRelease: async (id: string) => { + await apiFetch(`/api/devices/${id}/cancel-release`, { method: 'POST' }); + set((s) => ({ + devices: s.devices.map((d) => + d.id === id ? { ...d, releaseRequestedAt: null } : d + ), + })); + }, }));