feat(P3.T7): RemoteRevokedScreen overlay for own-device revocation
This commit is contained in:
@@ -4,6 +4,7 @@ import { HashRouter, Navigate, Outlet, Route, Routes } from 'react-router-dom';
|
|||||||
import { AppShell } from './components/AppShell';
|
import { AppShell } from './components/AppShell';
|
||||||
import { CrashToast } from './components/CrashToast';
|
import { CrashToast } from './components/CrashToast';
|
||||||
import { ErrorBoundary } from './components/ErrorBoundary';
|
import { ErrorBoundary } from './components/ErrorBoundary';
|
||||||
|
import { RemoteRevokedScreen } from './components/RemoteRevokedScreen';
|
||||||
import { SpinnerIcon } from './components/icons';
|
import { SpinnerIcon } from './components/icons';
|
||||||
import { UpdateToast } from './components/UpdateToast';
|
import { UpdateToast } from './components/UpdateToast';
|
||||||
import { RequireAdmin, RequireAuth, RequireDevice } from './components/guards';
|
import { RequireAdmin, RequireAuth, RequireDevice } from './components/guards';
|
||||||
@@ -168,6 +169,7 @@ export function App() {
|
|||||||
</Routes>
|
</Routes>
|
||||||
<UpdateToast />
|
<UpdateToast />
|
||||||
<CrashToast />
|
<CrashToast />
|
||||||
|
<RemoteRevokedScreen />
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
</CallProvider>
|
</CallProvider>
|
||||||
</ConversationsProvider>
|
</ConversationsProvider>
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { useAuth } from '../context/AuthContext';
|
||||||
|
|
||||||
|
export function RemoteRevokedScreen() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { revokedRemotely, acknowledgeRevocation } = useAuth();
|
||||||
|
|
||||||
|
if (!revokedRemotely) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role="alertdialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-labelledby="remote-revoked-title"
|
||||||
|
className="fixed inset-0 z-[1000] flex items-center justify-center bg-ink-950/95 p-6"
|
||||||
|
>
|
||||||
|
<div className="max-w-sm rounded-2xl border border-line bg-surface-2 p-6 text-center shadow-xl">
|
||||||
|
<h2
|
||||||
|
id="remote-revoked-title"
|
||||||
|
className="mb-2 font-display text-xl font-semibold text-fg"
|
||||||
|
>
|
||||||
|
{t('app:auth.revoked_title', { defaultValue: 'Du wurdest remote abgemeldet' })}
|
||||||
|
</h2>
|
||||||
|
<p className="mb-5 text-sm text-fg-muted">
|
||||||
|
{t('app:auth.revoked_body', {
|
||||||
|
defaultValue:
|
||||||
|
'Ein anderes deiner Geräte hat diesen Login beendet. Aus Sicherheitsgründen wurden alle lokalen Daten gelöscht.',
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={acknowledgeRevocation}
|
||||||
|
className="inline-flex cursor-pointer items-center justify-center rounded-lg bg-accent px-4 py-2 text-sm font-semibold text-accent-fg transition hover:brightness-110 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/40"
|
||||||
|
>
|
||||||
|
{t('app:auth.revoked_acknowledge', { defaultValue: 'Verstanden' })}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user