diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index caeaf1e..ae16f14 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -41,6 +41,7 @@ import { wsManager } from './services/websocket' import type { OrderPushMessage } from './types' import { apiService } from './services/api' import { hasToken } from './utils' +import ClobMigrationModal, { STORAGE_KEY as CLOB_MIGRATION_KEY } from './components/ClobMigrationModal' /** * 路由保护组件 @@ -64,6 +65,7 @@ function App() { const { t, i18n } = useTranslation() const [isFirstUse, setIsFirstUse] = useState(null) const [checking, setChecking] = useState(true) + const [clobMigrationVisible, setClobMigrationVisible] = useState(false) // 根据当前语言设置 Ant Design 的 locale const getAntdLocale = () => { @@ -199,6 +201,13 @@ function App() { wsManager.disconnect() } }, [checking, isFirstUse]) + + // 已登录且未查看过 CLOB V2 迁移提醒时显示弹窗 + useEffect(() => { + if (!checking && isFirstUse === false && hasToken() && !localStorage.getItem(CLOB_MIGRATION_KEY)) { + setClobMigrationVisible(true) + } + }, [checking, isFirstUse]) // 订阅订单推送并显示全局通知 useEffect(() => { @@ -284,6 +293,7 @@ function App() { {/* 默认重定向到登录页 */} } /> + setClobMigrationVisible(false)} /> ) diff --git a/frontend/src/components/ClobMigrationModal.tsx b/frontend/src/components/ClobMigrationModal.tsx new file mode 100644 index 0000000..09cd51c --- /dev/null +++ b/frontend/src/components/ClobMigrationModal.tsx @@ -0,0 +1,64 @@ +import { Modal, Button, Space } from 'antd' +import { SwapOutlined } from '@ant-design/icons' +import { useTranslation } from 'react-i18next' +import { useNavigate } from 'react-router-dom' + +const STORAGE_KEY = 'clob_v2_migration_dismissed' + +interface ClobMigrationModalProps { + open: boolean + onClose: () => void +} + +const ClobMigrationModal: React.FC = ({ open, onClose }) => { + const { t } = useTranslation() + const navigate = useNavigate() + + const handleClose = (dontRemind = false) => { + if (dontRemind) { + localStorage.setItem(STORAGE_KEY, 'true') + } + onClose() + } + + const handleGoToAccounts = () => { + localStorage.setItem(STORAGE_KEY, 'true') + onClose() + navigate('/accounts') + } + + return ( + + + {t('clobMigration.title')} + + } + open={open} + onCancel={() => handleClose()} + footer={ + + + + + + } + closable + maskClosable={false} + > +

+ {t('clobMigration.description')} +

+
+ ) +} + +export default ClobMigrationModal +export { STORAGE_KEY } diff --git a/frontend/src/locales/en/common.json b/frontend/src/locales/en/common.json index 48dae45..edb5e7a 100644 --- a/frontend/src/locales/en/common.json +++ b/frontend/src/locales/en/common.json @@ -1801,5 +1801,14 @@ "maxSizeUpdated": "Updated to max size", "periodChanged": "Period has changed, popup closed" } + }, + "clobMigration": { + "title": "CLOB 2.0 Migration Notice", + "description": "Polymarket CLOB has been upgraded to V2. Please go to the Accounts page to complete the USDC migration to ensure trading functions properly.", + "goToAccounts": "Go to Accounts", + "dontRemind": "Don't remind again", + "accountGuide": "CLOB V2 requires pUSD for trading. Click the USDC.e → pUSD button in the account actions to complete the migration.", + "accountGuideButton": "USDC.e → pUSD", + "dismissGuide": "Got it" } } \ No newline at end of file diff --git a/frontend/src/locales/zh-CN/common.json b/frontend/src/locales/zh-CN/common.json index a39316d..741a5f6 100644 --- a/frontend/src/locales/zh-CN/common.json +++ b/frontend/src/locales/zh-CN/common.json @@ -1801,5 +1801,14 @@ "maxSizeUpdated": "已更新为最大数量", "periodChanged": "周期已切换,弹窗已关闭" } + }, + "clobMigration": { + "title": "CLOB 2.0 迁移提醒", + "description": "Polymarket CLOB 已升级至 V2 版本,您需要前往账户页完成 USDC 迁移操作,以确保交易功能正常使用。", + "goToAccounts": "前往账户页", + "dontRemind": "不再提醒", + "accountGuide": "CLOB V2 需要 pUSD 进行交易,请点击账户操作栏中的 USDC.e → pUSD 按钮完成迁移。", + "accountGuideButton": "USDC.e → pUSD", + "dismissGuide": "知道了" } } \ No newline at end of file diff --git a/frontend/src/locales/zh-TW/common.json b/frontend/src/locales/zh-TW/common.json index beebeaa..c236561 100644 --- a/frontend/src/locales/zh-TW/common.json +++ b/frontend/src/locales/zh-TW/common.json @@ -1801,5 +1801,14 @@ "maxSizeUpdated": "已更新為最大數量", "periodChanged": "週期已切換,彈窗已關閉" } + }, + "clobMigration": { + "title": "CLOB 2.0 遷移提醒", + "description": "Polymarket CLOB 已升級至 V2 版本,您需要前往帳戶頁完成 USDC 遷移操作,以確保交易功能正常使用。", + "goToAccounts": "前往帳戶頁", + "dontRemind": "不再提醒", + "accountGuide": "CLOB V2 需要 pUSD 進行交易,請點擊帳戶操作欄中的 USDC.e → pUSD 按鈕完成遷移。", + "accountGuideButton": "USDC.e → pUSD", + "dismissGuide": "知道了" } } \ No newline at end of file diff --git a/frontend/src/pages/AccountList.tsx b/frontend/src/pages/AccountList.tsx index a1e3377..505878a 100644 --- a/frontend/src/pages/AccountList.tsx +++ b/frontend/src/pages/AccountList.tsx @@ -29,7 +29,9 @@ const AccountList: React.FC = () => { const [accountImportModalVisible, setAccountImportModalVisible] = useState(false) const [accountImportForm] = Form.useForm() const [wrapLoading, setWrapLoading] = useState>({}) + const [migrationGuideVisible, setMigrationGuideVisible] = useState(false) + const ACCOUNT_GUIDE_KEY = 'clob_v2_account_guide_dismissed' const handleWrapToPusd = async (account: Account) => { try { setWrapLoading(prev => ({ ...prev, [account.id]: true })) @@ -70,6 +72,13 @@ const AccountList: React.FC = () => { fetchAccounts() }, [fetchAccounts]) + // 首次进入且有账户时显示迁移引导 + useEffect(() => { + if (!loading && accounts.length > 0 && !localStorage.getItem(ACCOUNT_GUIDE_KEY)) { + setMigrationGuideVisible(true) + } + }, [loading, accounts.length]) + const handleAccountImportSuccess = async () => { message.success(t('accountImport.importSuccess')) setAccountImportModalVisible(false) @@ -363,7 +372,7 @@ const AccountList: React.FC = () => { } const balanceObj = balanceMap[record.id] const balance = balanceObj?.total || record.balance || '-' - return balance && balance !== '-' && typeof balance === 'string' ? `${formatUSDC(balance)} USDC` : '-' + return balance && balance !== '-' && typeof balance === 'string' ? `$${formatUSDC(balance)}` : '-' } }, { @@ -496,6 +505,38 @@ const AccountList: React.FC = () => { + {migrationGuideVisible && !loading && accounts.length > 0 && ( + } + closable + onClose={() => { + localStorage.setItem(ACCOUNT_GUIDE_KEY, 'true') + setMigrationGuideVisible(false) + }} + afterClose={() => { + localStorage.setItem(ACCOUNT_GUIDE_KEY, 'true') + setMigrationGuideVisible(false) + }} + style={{ marginBottom: 16, ...(isMobile ? { margin: '0 8px 12px' } : {}) }} + action={ + + } + /> + )} + { {t('accountList.totalBalance')}
- {balance?.total && balance.total !== '-' ? `${formatUSDC(balance.total)} USDC` : '- USDC'} + {balance?.total && balance.total !== '-' ? `$${formatUSDC(balance.total)}` : '-'}
@@ -626,6 +667,16 @@ const AccountList: React.FC = () => {
+ +
handleWrapToPusd(account)} + style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', cursor: wrapLoading[account.id] ? 'wait' : 'pointer', padding: '4px 8px' }} + > + + {t('clobMigration.accountGuideButton')} +
+
+ { ) : detailBalance ? ( - {formatUSDC(detailBalance.total)} USDC + ${formatUSDC(detailBalance.total)} ) : ( - @@ -797,7 +848,7 @@ const AccountList: React.FC = () => { ) : detailBalance ? ( - {formatUSDC(detailBalance.available)} USDC + ${formatUSDC(detailBalance.available)} ) : ( - @@ -808,7 +859,7 @@ const AccountList: React.FC = () => { ) : detailBalance ? ( - {formatUSDC(detailBalance.position)} USDC + ${formatUSDC(detailBalance.position)} ) : ( - @@ -864,7 +915,7 @@ const AccountList: React.FC = () => { fontWeight: 'bold', color: detailAccount.totalPnl && detailAccount.totalPnl.startsWith('-') ? '#ff4d4f' : '#52c41a' }}> - {formatUSDC(detailAccount.totalPnl)} USDC + ${formatUSDC(detailAccount.totalPnl)} )}