Files
fotospiel-app/resources/js/admin/mobile/AuthCallbackPage.tsx
Codex Agent b1f9f7cee0
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Fix TypeScript typecheck errors
2026-01-30 15:56:06 +01:00

83 lines
2.7 KiB
TypeScript

import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Card } from '@tamagui/card';
import { YStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Spinner } from 'tamagui';
import { useAuth } from '../auth/context';
import { ADMIN_DEFAULT_AFTER_LOGIN_PATH } from '../constants';
import { decodeReturnTo, resolveReturnTarget } from '../lib/returnTo';
import { useAdminTheme } from './theme';
import { useDocumentTitle } from './hooks/useDocumentTitle';
export default function AuthCallbackPage(): React.ReactElement {
const { status } = useAuth();
const navigate = useNavigate();
const { t } = useTranslation('auth');
const [redirected, setRedirected] = React.useState(false);
const { textStrong, muted, border, surface, shadow, appBackground } = useAdminTheme();
const safeAreaStyle: React.CSSProperties = {
paddingTop: 'calc(env(safe-area-inset-top, 0px) + 16px)',
paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) + 16px)',
};
useDocumentTitle(t('processing.title', 'Signing you in …'));
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 (
<YStack
alignItems="center"
justifyContent="center"
padding="$4"
style={{ minHeight: '100vh', backgroundImage: appBackground, ...safeAreaStyle }}
backgroundColor={surface}
>
<Card
borderRadius={22}
borderWidth={2}
borderColor={border}
backgroundColor={surface}
padding="$3"
shadowColor={shadow}
shadowOpacity={0.16}
shadowRadius={16}
shadowOffset={{ width: 0, height: 10 }}
>
<YStack alignItems="center" space="$2">
<Spinner size="small" color={textStrong} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('processing.title', 'Signing you in …')}
</Text>
<Text fontSize="$xs" color={muted} textAlign="center">
{t('processing.copy', 'One moment please while we prepare your dashboard.')}
</Text>
</YStack>
</Card>
</YStack>
);
}