mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-15 16:56:56 +08:00
Merge pull request #404 from 0xEmberZz/feature/binance-guide
feat: Add Binance setup guide with tutorial modal
This commit is contained in:
BIN
web/public/images/guide.png
Normal file
BIN
web/public/images/guide.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 712 KiB |
@@ -8,7 +8,7 @@ import { useAuth } from '../contexts/AuthContext';
|
|||||||
import { getExchangeIcon } from './ExchangeIcons';
|
import { getExchangeIcon } from './ExchangeIcons';
|
||||||
import { getModelIcon } from './ModelIcons';
|
import { getModelIcon } from './ModelIcons';
|
||||||
import { TraderConfigModal } from './TraderConfigModal';
|
import { TraderConfigModal } from './TraderConfigModal';
|
||||||
import { Bot, Brain, Landmark, BarChart3, Trash2, Plus, Users, AlertTriangle } from 'lucide-react';
|
import { Bot, Brain, Landmark, BarChart3, Trash2, Plus, Users, AlertTriangle, BookOpen } from 'lucide-react';
|
||||||
|
|
||||||
// 获取友好的AI模型名称
|
// 获取友好的AI模型名称
|
||||||
function getModelDisplayName(modelId: string): string {
|
function getModelDisplayName(modelId: string): string {
|
||||||
@@ -1162,10 +1162,11 @@ function ExchangeConfigModal({
|
|||||||
const [secretKey, setSecretKey] = useState('');
|
const [secretKey, setSecretKey] = useState('');
|
||||||
const [passphrase, setPassphrase] = useState('');
|
const [passphrase, setPassphrase] = useState('');
|
||||||
const [testnet, setTestnet] = useState(false);
|
const [testnet, setTestnet] = useState(false);
|
||||||
|
const [showGuide, setShowGuide] = useState(false);
|
||||||
|
|
||||||
// Hyperliquid 特定字段
|
// Hyperliquid 特定字段
|
||||||
const [hyperliquidWalletAddr, setHyperliquidWalletAddr] = useState('');
|
const [hyperliquidWalletAddr, setHyperliquidWalletAddr] = useState('');
|
||||||
|
|
||||||
// Aster 特定字段
|
// Aster 特定字段
|
||||||
const [asterUser, setAsterUser] = useState('');
|
const [asterUser, setAsterUser] = useState('');
|
||||||
const [asterSigner, setAsterSigner] = useState('');
|
const [asterSigner, setAsterSigner] = useState('');
|
||||||
@@ -1226,21 +1227,34 @@ function ExchangeConfigModal({
|
|||||||
<h3 className="text-xl font-bold" style={{ color: '#EAECEF' }}>
|
<h3 className="text-xl font-bold" style={{ color: '#EAECEF' }}>
|
||||||
{editingExchangeId ? t('editExchange', language) : t('addExchange', language)}
|
{editingExchangeId ? t('editExchange', language) : t('addExchange', language)}
|
||||||
</h3>
|
</h3>
|
||||||
{editingExchangeId && (
|
<div className="flex items-center gap-2">
|
||||||
<button
|
{selectedExchange?.id === 'binance' && (
|
||||||
type="button"
|
<button
|
||||||
onClick={() => {
|
type="button"
|
||||||
if (confirm(t('confirmDeleteExchange', language))) {
|
onClick={() => setShowGuide(true)}
|
||||||
onDelete(editingExchangeId);
|
className="px-3 py-2 rounded text-sm font-semibold transition-all hover:scale-105 flex items-center gap-2"
|
||||||
}
|
style={{ background: 'rgba(240, 185, 11, 0.1)', color: '#F0B90B' }}
|
||||||
}}
|
>
|
||||||
className="p-2 rounded hover:bg-red-100 transition-colors"
|
<BookOpen className="w-4 h-4" />
|
||||||
style={{ background: 'rgba(246, 70, 93, 0.1)', color: '#F6465D' }}
|
{t('viewGuide', language)}
|
||||||
title={t('deleteConfigFailed', language)}
|
</button>
|
||||||
>
|
)}
|
||||||
<Trash2 className="w-4 h-4" />
|
{editingExchangeId && (
|
||||||
</button>
|
<button
|
||||||
)}
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
if (confirm(t('confirmDeleteExchange', language))) {
|
||||||
|
onDelete(editingExchangeId);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="p-2 rounded hover:bg-red-100 transition-colors"
|
||||||
|
style={{ background: 'rgba(246, 70, 93, 0.1)', color: '#F6465D' }}
|
||||||
|
title={t('deleteConfigFailed', language)}
|
||||||
|
>
|
||||||
|
<Trash2 className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="space-y-4">
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
@@ -1468,7 +1482,7 @@ function ExchangeConfigModal({
|
|||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={
|
disabled={
|
||||||
!selectedExchange ||
|
!selectedExchange ||
|
||||||
(selectedExchange.id === 'binance' && (!apiKey.trim() || !secretKey.trim())) ||
|
(selectedExchange.id === 'binance' && (!apiKey.trim() || !secretKey.trim())) ||
|
||||||
(selectedExchange.id === 'okx' && (!apiKey.trim() || !secretKey.trim() || !passphrase.trim())) ||
|
(selectedExchange.id === 'okx' && (!apiKey.trim() || !secretKey.trim() || !passphrase.trim())) ||
|
||||||
(selectedExchange.id === 'hyperliquid' && (!apiKey.trim() || !hyperliquidWalletAddr.trim())) ||
|
(selectedExchange.id === 'hyperliquid' && (!apiKey.trim() || !hyperliquidWalletAddr.trim())) ||
|
||||||
@@ -1483,6 +1497,34 @@ function ExchangeConfigModal({
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Binance Setup Guide Modal */}
|
||||||
|
{showGuide && (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-4" onClick={() => setShowGuide(false)}>
|
||||||
|
<div className="bg-gray-800 rounded-lg p-6 w-full max-w-4xl relative" style={{ background: '#1E2329' }} onClick={(e) => e.stopPropagation()}>
|
||||||
|
<div className="flex items-center justify-between mb-4">
|
||||||
|
<h3 className="text-xl font-bold flex items-center gap-2" style={{ color: '#EAECEF' }}>
|
||||||
|
<BookOpen className="w-6 h-6" style={{ color: '#F0B90B' }} />
|
||||||
|
{t('binanceSetupGuide', language)}
|
||||||
|
</h3>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowGuide(false)}
|
||||||
|
className="px-4 py-2 rounded text-sm font-semibold transition-all hover:scale-105"
|
||||||
|
style={{ background: '#2B3139', color: '#848E9C' }}
|
||||||
|
>
|
||||||
|
{t('closeGuide', language)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="overflow-y-auto max-h-[80vh]">
|
||||||
|
<img
|
||||||
|
src="/images/guide.png"
|
||||||
|
alt={t('binanceSetupGuide', language)}
|
||||||
|
className="w-full h-auto rounded"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,6 +257,9 @@ export const translations = {
|
|||||||
exchangeConfigWarning2: '• Do not grant withdrawal permissions to ensure fund security',
|
exchangeConfigWarning2: '• Do not grant withdrawal permissions to ensure fund security',
|
||||||
exchangeConfigWarning3: '• After deleting configuration, related traders will not be able to trade',
|
exchangeConfigWarning3: '• After deleting configuration, related traders will not be able to trade',
|
||||||
edit: 'Edit',
|
edit: 'Edit',
|
||||||
|
viewGuide: 'View Guide',
|
||||||
|
binanceSetupGuide: 'Binance Setup Guide',
|
||||||
|
closeGuide: 'Close',
|
||||||
|
|
||||||
// Error Messages
|
// Error Messages
|
||||||
createTraderFailed: 'Failed to create trader',
|
createTraderFailed: 'Failed to create trader',
|
||||||
@@ -671,6 +674,9 @@ export const translations = {
|
|||||||
exchangeConfigWarning2: '• 不要授予提现权限,确保资金安全',
|
exchangeConfigWarning2: '• 不要授予提现权限,确保资金安全',
|
||||||
exchangeConfigWarning3: '• 删除配置后,相关交易员将无法正常交易',
|
exchangeConfigWarning3: '• 删除配置后,相关交易员将无法正常交易',
|
||||||
edit: '编辑',
|
edit: '编辑',
|
||||||
|
viewGuide: '查看教程',
|
||||||
|
binanceSetupGuide: '币安配置教程',
|
||||||
|
closeGuide: '关闭',
|
||||||
|
|
||||||
// Error Messages
|
// Error Messages
|
||||||
createTraderFailed: '创建交易员失败',
|
createTraderFailed: '创建交易员失败',
|
||||||
|
|||||||
Reference in New Issue
Block a user