mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
refactor: review round 2 — remove dead code, fix type safety, improve UX
- Remove LinkOAuthCallback.tsx (dead code) and its route from App.tsx - Move LINK_OAUTH_* constants to OAuthCallback.tsx - Replace local ServerLinkResult with LinkCallbackResponse from types - Move merge navigate() from render body to useEffect - Track errorMode to show correct CTA (Return to Telegram vs Back to Login) - Remove non-null assertions with proper narrowing - Extract getErrorDetail helper for error casting - Add smart polling success detection (stop + toast when linked count increases)
This commit is contained in:
@@ -9,7 +9,7 @@ import { Card } from '@/components/data-display/Card';
|
||||
import { Button } from '@/components/primitives/Button';
|
||||
import { staggerContainer, staggerItem } from '@/components/motion/transitions';
|
||||
import ProviderIcon from '../components/ProviderIcon';
|
||||
import { LINK_OAUTH_STATE_KEY, LINK_OAUTH_PROVIDER_KEY } from './LinkOAuthCallback';
|
||||
import { LINK_OAUTH_STATE_KEY, LINK_OAUTH_PROVIDER_KEY } from './OAuthCallback';
|
||||
import { getTelegramInitData } from '../hooks/useTelegramSDK';
|
||||
import { usePlatform, useIsTelegram } from '@/platform/hooks/usePlatform';
|
||||
import type { LinkedProvider } from '../types';
|
||||
@@ -98,6 +98,7 @@ export default function ConnectedAccounts() {
|
||||
const [confirmingUnlink, setConfirmingUnlink] = useState<string | null>(null);
|
||||
const [linkingProvider, setLinkingProvider] = useState<string | null>(null);
|
||||
const [waitingExternalLink, setWaitingExternalLink] = useState(false);
|
||||
const linkedCountBeforePolling = useRef<number | null>(null);
|
||||
const blurTimeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);
|
||||
|
||||
const inTelegram = useIsTelegram();
|
||||
@@ -124,6 +125,18 @@ export default function ConnectedAccounts() {
|
||||
return () => clearTimeout(timeout);
|
||||
}, [waitingExternalLink]);
|
||||
|
||||
// Detect successful external link: stop polling and show toast when linked count increases
|
||||
useEffect(() => {
|
||||
if (!waitingExternalLink || !data) return;
|
||||
const currentLinked = data.providers.filter((p) => p.linked).length;
|
||||
if (linkedCountBeforePolling.current === null) return;
|
||||
if (currentLinked > linkedCountBeforePolling.current) {
|
||||
setWaitingExternalLink(false);
|
||||
linkedCountBeforePolling.current = null;
|
||||
showToast({ type: 'success', message: t('profile.accounts.linkSuccess') });
|
||||
}
|
||||
}, [data, waitingExternalLink, showToast, t]);
|
||||
|
||||
const unlinkMutation = useMutation({
|
||||
mutationFn: (provider: string) => authApi.unlinkProvider(provider),
|
||||
onSuccess: () => {
|
||||
@@ -162,6 +175,8 @@ export default function ConnectedAccounts() {
|
||||
// The callback will use server-complete flow (auth via state token, no JWT).
|
||||
platform.openLink(authorize_url);
|
||||
setLinkingProvider(null);
|
||||
// Snapshot current linked count before polling starts
|
||||
linkedCountBeforePolling.current = data?.providers.filter((p) => p.linked).length ?? 0;
|
||||
// Start polling for linked providers (external browser has no way to notify Mini App)
|
||||
setWaitingExternalLink(true);
|
||||
showToast({
|
||||
|
||||
Reference in New Issue
Block a user