refactor(auth): migrate user center logout and refactor callback logic

- Migrate from static `Modal.confirm` to `App.useModal` in UserCenter for better context support.
- Refactor Logto Callback page:
  - Remove unused `useEffect` dependency on `isAuthenticated`.
  - Inline redirect logic directly into the `onSuccess` callback of `useHandleSignInCallback`.
  - Preserve existing redirect flow logic while simplifying the component structure.
This commit is contained in:
kyuuseiryuu 2026-03-10 12:50:00 +09:00
parent 2032cec715
commit 73354d0394
2 changed files with 48 additions and 53 deletions

View File

@ -1,28 +1,20 @@
import { useHandleSignInCallback } from '@logto/react';
import { Spin } from 'antd';
import { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router';
import { useNavigate } from 'react-router';
export const CallbackPage = () => {
const navigate = useNavigate();
const { isLoading, isAuthenticated, error } = useHandleSignInCallback(() => {
// Navigate to root path when finished
const redirect = sessionStorage.getItem('redirect');
if (redirect) {
sessionStorage.removeItem('redirect');
navigate(redirect);
} else {
navigate('/user-center');
}
});
const navigate = useNavigate();
const location = useLocation();
useEffect(() => {
if (isAuthenticated) {
console.debug({ isLoading, isAuthenticated, error });
const redirect = sessionStorage.getItem('redirect');
if (redirect) {
navigate(redirect);
sessionStorage.removeItem('redirect');
} else {
navigate('/user-center');
}
}
}, [isAuthenticated]);
// When it's working in progress
if (isLoading) {
return (
<Spin spinning>

View File

@ -1,6 +1,6 @@
import { EditOutlined, FileTextOutlined, HomeOutlined, KeyOutlined, LockOutlined, LoginOutlined, LogoutOutlined, MailOutlined, MobileOutlined } from "@ant-design/icons";
import { useLogto, type IdTokenClaims } from "@logto/react";
import { Avatar, Button, Divider, Flex, Modal, Typography } from "antd";
import { App, Avatar, Button, Divider, Flex, Modal, Typography } from "antd";
import { useCallback, useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router";
@ -39,6 +39,7 @@ export const UserCenter = () => {
const handleModifyInfo = useCallback((url: string) => {
window.location.href = `${logto}${url}?redirect=${redirect}`;
}, []);
const [modal, contextHolder] = Modal.useModal();
if (!isAuthenticated) {
return (
<div className="app">
@ -54,42 +55,44 @@ export const UserCenter = () => {
</div>
);
}
console.debug(user);
return (
<Flex className="app" gap={12} vertical align="center" style={{ maxWidth: 600 }}>
<Avatar size={128} src={user?.picture ?? user?.name} />
<Flex>
<Typography.Text>{user?.username ?? user?.name ?? '未设置'}</Typography.Text>
<>
{contextHolder}
<Flex className="app" gap={12} vertical align="center" style={{ maxWidth: 600 }}>
<Avatar size={128} src={user?.picture ?? user?.name} />
<Flex>
<Typography.Text>{user?.username ?? user?.name ?? '未设置'}</Typography.Text>
</Flex>
<Divider></Divider>
<Button block icon={<EditOutlined />} onClick={() => handleModifyInfo(modifyRoutes.username)}>({user?.username ?? '未设置'})</Button>
<Button block icon={<MailOutlined />} onClick={() => handleModifyInfo(modifyRoutes.email)}> E-Mail</Button>
<Button block icon={<LockOutlined />} onClick={() => handleModifyInfo(modifyRoutes.auth_app)}></Button>
<Button block icon={<MobileOutlined />} onClick={() => handleModifyInfo(modifyRoutes.auth_app)}></Button>
<Button block icon={<KeyOutlined />} onClick={() => handleModifyInfo(modifyRoutes.passkey)}> Passkey</Button>
<Button block icon={<FileTextOutlined />} onClick={() => handleModifyInfo(modifyRoutes.backup_code)}></Button>
<Divider />
<Button block type="primary" onClick={() => navigate('/')} icon={<HomeOutlined />}></Button>
<Divider />
<Button
block
danger
icon={<LoginOutlined />}
onClick={() => modal.confirm({
maskClosable: true,
title: '确认登出?',
cancelText: '保持登录',
cancelButtonProps: { icon: <HomeOutlined /> },
okText: '确认登出',
okButtonProps: {
icon: <LogoutOutlined />,
danger: true,
},
onOk: () => signOut(`${window.location.origin}/user-center`),
})}
>
</Button>
</Flex>
<Divider></Divider>
<Button block icon={<EditOutlined />} onClick={() => handleModifyInfo(modifyRoutes.username)}>({user?.username ?? '未设置'})</Button>
<Button block icon={<MailOutlined />} onClick={() => handleModifyInfo(modifyRoutes.email)}> E-Mail</Button>
<Button block icon={<LockOutlined />} onClick={() => handleModifyInfo(modifyRoutes.auth_app)}></Button>
<Button block icon={<MobileOutlined />} onClick={() => handleModifyInfo(modifyRoutes.auth_app)}></Button>
<Button block icon={<KeyOutlined />} onClick={() => handleModifyInfo(modifyRoutes.passkey)}> Passkey</Button>
<Button block icon={<FileTextOutlined />} onClick={() => handleModifyInfo(modifyRoutes.backup_code)}></Button>
<Divider />
<Button block type="primary" onClick={() => navigate('/')} icon={<HomeOutlined />}></Button>
<Divider />
<Button
block
danger
icon={<LoginOutlined />}
onClick={() => Modal.confirm({
title: '确认登出?',
cancelText: '回到首页',
cancelButtonProps: { icon: <HomeOutlined /> },
onCancel: () => navigate('/'),
okText: '确认登出',
okButtonProps: {
icon: <LogoutOutlined />,
danger: true,
},
onOk: () => signOut(`${window.location.origin}/user-center`),
})}
>
</Button>
</Flex>
</>
);
}