45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import React from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useAuth } from '../auth/context';
|
|
import { ADMIN_DEFAULT_AFTER_LOGIN_PATH } from '../constants';
|
|
import { decodeReturnTo, resolveReturnTarget } from '../lib/returnTo';
|
|
|
|
export default function AuthCallbackPage(): React.ReactElement {
|
|
const { status } = useAuth();
|
|
const navigate = useNavigate();
|
|
const { t } = useTranslation('auth');
|
|
const [redirected, setRedirected] = React.useState(false);
|
|
|
|
const searchParams = React.useMemo(() => new URLSearchParams(window.location.search), []);
|
|
const rawReturnTo = searchParams.get('return_to');
|
|
|
|
const fallback = ADMIN_DEFAULT_AFTER_LOGIN_PATH;
|
|
const destination = React.useMemo(() => {
|
|
if (rawReturnTo) {
|
|
const decoded = decodeReturnTo(rawReturnTo);
|
|
if (decoded) {
|
|
return decoded;
|
|
}
|
|
}
|
|
|
|
return resolveReturnTarget(null, fallback).finalTarget;
|
|
}, [fallback, rawReturnTo]);
|
|
|
|
React.useEffect(() => {
|
|
if (status !== 'authenticated' || redirected) {
|
|
return;
|
|
}
|
|
|
|
setRedirected(true);
|
|
navigate(destination, { replace: true });
|
|
}, [destination, navigate, redirected, status]);
|
|
|
|
return (
|
|
<div className="flex min-h-screen flex-col items-center justify-center gap-3 p-6 text-center text-sm text-muted-foreground">
|
|
<span className="text-base font-medium text-foreground">{t('processing.title', 'Signing you in …')}</span>
|
|
<p className="max-w-xs text-xs text-muted-foreground">{t('processing.copy', 'One moment please while we prepare your dashboard.')}</p>
|
|
</div>
|
|
);
|
|
}
|