mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-15 16:56:56 +08:00
refactor: replace window.location with useNavigate for routing in auth components (#1470)
Co-authored-by: Dean <afei.wuhao@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import useSWR from 'swr'
|
||||
import {
|
||||
TrendingUp,
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
Activity,
|
||||
Terminal,
|
||||
Cpu,
|
||||
Database
|
||||
Database,
|
||||
} from 'lucide-react'
|
||||
import { useLanguage } from '../contexts/LanguageContext'
|
||||
import { useAuth } from '../contexts/AuthContext'
|
||||
@@ -39,14 +40,24 @@ interface PublicStrategy {
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
const strategyStyles: Record<string, { color: string; border: string; glow: string; shadow: string; icon: any; bg: string }> = {
|
||||
const strategyStyles: Record<
|
||||
string,
|
||||
{
|
||||
color: string
|
||||
border: string
|
||||
glow: string
|
||||
shadow: string
|
||||
icon: any
|
||||
bg: string
|
||||
}
|
||||
> = {
|
||||
scalper: {
|
||||
color: 'text-[#F0B90B]',
|
||||
border: 'border-[#F0B90B]/30',
|
||||
glow: 'shadow-[0_0_20px_rgba(240,185,11,0.15)]',
|
||||
shadow: 'hover:shadow-[0_0_30px_rgba(240,185,11,0.25)]',
|
||||
bg: 'bg-[#F0B90B]/5',
|
||||
icon: Zap
|
||||
icon: Zap,
|
||||
},
|
||||
swing: {
|
||||
color: 'text-cyan-400',
|
||||
@@ -54,7 +65,7 @@ const strategyStyles: Record<string, { color: string; border: string; glow: stri
|
||||
glow: 'shadow-[0_0_20px_rgba(34,211,238,0.15)]',
|
||||
shadow: 'hover:shadow-[0_0_30px_rgba(34,211,238,0.25)]',
|
||||
bg: 'bg-cyan-400/5',
|
||||
icon: TrendingUp
|
||||
icon: TrendingUp,
|
||||
},
|
||||
arbitrage: {
|
||||
color: 'text-purple-400',
|
||||
@@ -62,7 +73,7 @@ const strategyStyles: Record<string, { color: string; border: string; glow: stri
|
||||
glow: 'shadow-[0_0_20px_rgba(192,132,252,0.15)]',
|
||||
shadow: 'hover:shadow-[0_0_30px_rgba(192,132,252,0.25)]',
|
||||
bg: 'bg-purple-400/5',
|
||||
icon: Layers
|
||||
icon: Layers,
|
||||
},
|
||||
conservative: {
|
||||
color: 'text-emerald-400',
|
||||
@@ -70,7 +81,7 @@ const strategyStyles: Record<string, { color: string; border: string; glow: stri
|
||||
glow: 'shadow-[0_0_20px_rgba(52,211,153,0.15)]',
|
||||
shadow: 'hover:shadow-[0_0_30px_rgba(52,211,153,0.25)]',
|
||||
bg: 'bg-emerald-400/5',
|
||||
icon: Shield
|
||||
icon: Shield,
|
||||
},
|
||||
aggressive: {
|
||||
color: 'text-red-500',
|
||||
@@ -78,7 +89,7 @@ const strategyStyles: Record<string, { color: string; border: string; glow: stri
|
||||
glow: 'shadow-[0_0_20px_rgba(239,68,68,0.15)]',
|
||||
shadow: 'hover:shadow-[0_0_30px_rgba(239,68,68,0.25)]',
|
||||
bg: 'bg-red-500/5',
|
||||
icon: Target
|
||||
icon: Target,
|
||||
},
|
||||
default: {
|
||||
color: 'text-zinc-400',
|
||||
@@ -86,8 +97,8 @@ const strategyStyles: Record<string, { color: string; border: string; glow: stri
|
||||
glow: '',
|
||||
shadow: 'hover:shadow-[0_0_20px_rgba(255,255,255,0.05)]',
|
||||
bg: 'bg-zinc-800/20',
|
||||
icon: Activity
|
||||
}
|
||||
icon: Activity,
|
||||
},
|
||||
}
|
||||
|
||||
function getStrategyStyle(name: string) {
|
||||
@@ -95,12 +106,15 @@ function getStrategyStyle(name: string) {
|
||||
if (lowerName.includes('scalp')) return strategyStyles.scalper
|
||||
if (lowerName.includes('swing')) return strategyStyles.swing
|
||||
if (lowerName.includes('arb')) return strategyStyles.arbitrage
|
||||
if (lowerName.includes('safe') || lowerName.includes('conserv')) return strategyStyles.conservative
|
||||
if (lowerName.includes('aggress') || lowerName.includes('high')) return strategyStyles.aggressive
|
||||
if (lowerName.includes('safe') || lowerName.includes('conserv'))
|
||||
return strategyStyles.conservative
|
||||
if (lowerName.includes('aggress') || lowerName.includes('high'))
|
||||
return strategyStyles.aggressive
|
||||
return strategyStyles.default
|
||||
}
|
||||
|
||||
export function StrategyMarketPage() {
|
||||
const navigate = useNavigate()
|
||||
const { language } = useLanguage()
|
||||
const { token, user } = useAuth()
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
@@ -120,23 +134,28 @@ export function StrategyMarketPage() {
|
||||
},
|
||||
{
|
||||
refreshInterval: 60000,
|
||||
revalidateOnFocus: false
|
||||
revalidateOnFocus: false,
|
||||
}
|
||||
)
|
||||
|
||||
const filteredStrategies = strategies?.filter(s => {
|
||||
if (searchQuery) {
|
||||
const query = searchQuery.toLowerCase()
|
||||
return s.name.toLowerCase().includes(query) ||
|
||||
s.description?.toLowerCase().includes(query)
|
||||
}
|
||||
return true
|
||||
}) || []
|
||||
const filteredStrategies =
|
||||
strategies?.filter((s) => {
|
||||
if (searchQuery) {
|
||||
const query = searchQuery.toLowerCase()
|
||||
return (
|
||||
s.name.toLowerCase().includes(query) ||
|
||||
s.description?.toLowerCase().includes(query)
|
||||
)
|
||||
}
|
||||
return true
|
||||
}) || []
|
||||
|
||||
const handleCopyConfig = async (strategy: PublicStrategy) => {
|
||||
if (!strategy.config) return
|
||||
try {
|
||||
await navigator.clipboard.writeText(JSON.stringify(strategy.config, null, 2))
|
||||
await navigator.clipboard.writeText(
|
||||
JSON.stringify(strategy.config, null, 2)
|
||||
)
|
||||
setCopiedId(strategy.id)
|
||||
toast.success(tr('copied'))
|
||||
setTimeout(() => setCopiedId(null), 2000)
|
||||
@@ -147,14 +166,16 @@ export function StrategyMarketPage() {
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
const date = new Date(dateStr)
|
||||
return date.toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
}).replace(',', '')
|
||||
return date
|
||||
.toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
})
|
||||
.replace(',', '')
|
||||
}
|
||||
|
||||
const getIndicatorList = (config: any) => {
|
||||
@@ -174,15 +195,15 @@ export function StrategyMarketPage() {
|
||||
return (
|
||||
<DeepVoidBackground className="min-h-screen text-white font-mono py-12">
|
||||
<div className="w-full px-4 md:px-8 space-y-8">
|
||||
|
||||
<div className="w-full relative z-10">
|
||||
|
||||
{/* Header Section */}
|
||||
<div className="mb-12 border-b border-zinc-800 pb-8 relative">
|
||||
<div className="absolute top-0 right-0 p-2 border border-zinc-800 rounded bg-black/50 text-xs text-zinc-500 font-mono hidden md:block">
|
||||
SYSTEM_STATUS: <span className="text-emerald-500 animate-pulse">ONLINE</span>
|
||||
SYSTEM_STATUS:{' '}
|
||||
<span className="text-emerald-500 animate-pulse">ONLINE</span>
|
||||
<br />
|
||||
MARKET_UPLINK: <span className="text-emerald-500">ESTABLISHED</span>
|
||||
MARKET_UPLINK:{' '}
|
||||
<span className="text-emerald-500">ESTABLISHED</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
@@ -191,11 +212,15 @@ export function StrategyMarketPage() {
|
||||
<Database className="w-8 h-8 text-nofx-gold relative z-10" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold tracking-tighter text-white uppercase glitch-text" data-text={tr('title')}>
|
||||
<h1
|
||||
className="text-4xl font-bold tracking-tighter text-white uppercase glitch-text"
|
||||
data-text={tr('title')}
|
||||
>
|
||||
{tr('title')}
|
||||
</h1>
|
||||
<p className="text-xs text-nofx-gold tracking-[0.3em] font-bold mt-1">
|
||||
// {tr('subtitle')}
|
||||
{'// '}
|
||||
{tr('subtitle')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -232,16 +257,21 @@ export function StrategyMarketPage() {
|
||||
<button
|
||||
key={cat}
|
||||
onClick={() => setSelectedCategory(cat)}
|
||||
className={`px-4 py-2 text-xs font-mono uppercase tracking-wider transition-all relative overflow-hidden ${selectedCategory === cat
|
||||
? 'text-black font-bold'
|
||||
: 'text-zinc-500 hover:text-white'
|
||||
}`}
|
||||
className={`px-4 py-2 text-xs font-mono uppercase tracking-wider transition-all relative overflow-hidden ${
|
||||
selectedCategory === cat
|
||||
? 'text-black font-bold'
|
||||
: 'text-zinc-500 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
{selectedCategory === cat && (
|
||||
<motion.div
|
||||
layoutId="filter-highlight"
|
||||
className="absolute inset-0 bg-nofx-gold"
|
||||
transition={{ type: "spring", bounce: 0.2, duration: 0.6 }}
|
||||
transition={{
|
||||
type: 'spring',
|
||||
bounce: 0.2,
|
||||
duration: 0.6,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<span className="relative z-10">{tr(cat)}</span>
|
||||
@@ -260,11 +290,22 @@ export function StrategyMarketPage() {
|
||||
<Cpu size={24} className="text-nofx-gold/50" />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-nofx-gold text-xs tracking-widest animate-pulse">{tr('loading')}</p>
|
||||
<p className="text-nofx-gold text-xs tracking-widest animate-pulse">
|
||||
{tr('loading')}
|
||||
</p>
|
||||
<div className="flex gap-1">
|
||||
<div className="w-1 h-1 bg-nofx-gold rounded-full animate-bounce" style={{ animationDelay: '0s' }}></div>
|
||||
<div className="w-1 h-1 bg-nofx-gold rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
|
||||
<div className="w-1 h-1 bg-nofx-gold rounded-full animate-bounce" style={{ animationDelay: '0.4s' }}></div>
|
||||
<div
|
||||
className="w-1 h-1 bg-nofx-gold rounded-full animate-bounce"
|
||||
style={{ animationDelay: '0s' }}
|
||||
></div>
|
||||
<div
|
||||
className="w-1 h-1 bg-nofx-gold rounded-full animate-bounce"
|
||||
style={{ animationDelay: '0.2s' }}
|
||||
></div>
|
||||
<div
|
||||
className="w-1 h-1 bg-nofx-gold rounded-full animate-bounce"
|
||||
style={{ animationDelay: '0.4s' }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -279,7 +320,9 @@ export function StrategyMarketPage() {
|
||||
<h3 className="text-xl font-bold text-zinc-300 font-mono tracking-tight mb-2">
|
||||
[{tr('noStrategies')}]
|
||||
</h3>
|
||||
<p className="text-zinc-600 text-xs tracking-wide uppercase">{tr('noStrategiesDesc')}</p>
|
||||
<p className="text-zinc-600 text-xs tracking-wide uppercase">
|
||||
{tr('noStrategiesDesc')}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -290,9 +333,10 @@ export function StrategyMarketPage() {
|
||||
{filteredStrategies.map((strategy, i) => {
|
||||
const style = getStrategyStyle(strategy.name)
|
||||
const Icon = style.icon
|
||||
const indicators = strategy.config_visible && strategy.config
|
||||
? getIndicatorList(strategy.config)
|
||||
: []
|
||||
const indicators =
|
||||
strategy.config_visible && strategy.config
|
||||
? getIndicatorList(strategy.config)
|
||||
: []
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
@@ -304,16 +348,24 @@ export function StrategyMarketPage() {
|
||||
className={`group relative bg-black border border-zinc-800 hover:border-zinc-600 transition-all duration-300 ${style.shadow}`}
|
||||
>
|
||||
{/* Holographic Border Highlight */}
|
||||
<div className={`absolute top-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-${style.color.split('-')[1]}-500 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500`}></div>
|
||||
<div className={`absolute bottom-0 right-0 w-full h-[1px] bg-gradient-to-r from-transparent via-${style.color.split('-')[1]}-500 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500`}></div>
|
||||
<div
|
||||
className={`absolute top-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-${style.color.split('-')[1]}-500 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500`}
|
||||
></div>
|
||||
<div
|
||||
className={`absolute bottom-0 right-0 w-full h-[1px] bg-gradient-to-r from-transparent via-${style.color.split('-')[1]}-500 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500`}
|
||||
></div>
|
||||
|
||||
{/* Category Side Strip */}
|
||||
<div className={`absolute left-0 top-0 bottom-0 w-[2px] ${style.bg.replace('/5', '/50')}`}></div>
|
||||
<div
|
||||
className={`absolute left-0 top-0 bottom-0 w-[2px] ${style.bg.replace('/5', '/50')}`}
|
||||
></div>
|
||||
|
||||
<div className="p-6 relative">
|
||||
{/* Header */}
|
||||
<div className="flex justify-between items-start mb-6">
|
||||
<div className={`p-2 rounded-none border ${style.border} ${style.bg}`}>
|
||||
<div
|
||||
className={`p-2 rounded-none border ${style.border} ${style.bg}`}
|
||||
>
|
||||
<Icon className={`w-5 h-5 ${style.color}`} />
|
||||
</div>
|
||||
<div className="text-[10px] font-mono">
|
||||
@@ -332,7 +384,9 @@ export function StrategyMarketPage() {
|
||||
</div>
|
||||
|
||||
{/* Name and Description */}
|
||||
<h3 className={`text-lg font-bold mb-2 tracking-tight group-hover:${style.color} transition-colors uppercase truncate relative`}>
|
||||
<h3
|
||||
className={`text-lg font-bold mb-2 tracking-tight group-hover:${style.color} transition-colors uppercase truncate relative`}
|
||||
>
|
||||
{strategy.name}
|
||||
<span className="absolute -bottom-1 left-0 w-8 h-[2px] bg-zinc-800 group-hover:bg-nofx-gold transition-colors"></span>
|
||||
</h3>
|
||||
@@ -343,12 +397,22 @@ export function StrategyMarketPage() {
|
||||
{/* Meta Data */}
|
||||
<div className="grid grid-cols-2 gap-y-2 mb-6 text-[10px] font-mono text-zinc-600">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-zinc-700 uppercase">{tr('author')}</span>
|
||||
<span className="text-zinc-400 group-hover:text-white transition-colors">@{strategy.author_email?.split('@')[0] || 'UNKNOWN'}</span>
|
||||
<span className="text-zinc-700 uppercase">
|
||||
{tr('author')}
|
||||
</span>
|
||||
<span className="text-zinc-400 group-hover:text-white transition-colors">
|
||||
@
|
||||
{strategy.author_email?.split('@')[0] ||
|
||||
'UNKNOWN'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col text-right">
|
||||
<span className="text-zinc-700 uppercase">{tr('createdAt')}</span>
|
||||
<span className="text-zinc-400">{formatDate(strategy.created_at)}</span>
|
||||
<span className="text-zinc-700 uppercase">
|
||||
{tr('createdAt')}
|
||||
</span>
|
||||
<span className="text-zinc-400">
|
||||
{formatDate(strategy.created_at)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -358,14 +422,20 @@ export function StrategyMarketPage() {
|
||||
<div className="space-y-3">
|
||||
{/* Indicators */}
|
||||
<div className="flex items-center gap-2 overflow-x-auto scrollbar-hide pb-1">
|
||||
{indicators.length > 0 ? indicators.map((ind) => (
|
||||
<span
|
||||
key={ind}
|
||||
className="px-1.5 py-0.5 border border-zinc-700 bg-zinc-800 text-[9px] text-zinc-300 font-mono whitespace-nowrap"
|
||||
>
|
||||
{ind}
|
||||
{indicators.length > 0 ? (
|
||||
indicators.map((ind) => (
|
||||
<span
|
||||
key={ind}
|
||||
className="px-1.5 py-0.5 border border-zinc-700 bg-zinc-800 text-[9px] text-zinc-300 font-mono whitespace-nowrap"
|
||||
>
|
||||
{ind}
|
||||
</span>
|
||||
))
|
||||
) : (
|
||||
<span className="text-[9px] text-zinc-600">
|
||||
NO_INDICATORS
|
||||
</span>
|
||||
)) : <span className="text-[9px] text-zinc-600">NO_INDICATORS</span>}
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Risk Control */}
|
||||
@@ -373,22 +443,38 @@ export function StrategyMarketPage() {
|
||||
<div className="flex justify-between items-center text-[10px]">
|
||||
<div className="flex gap-3">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-zinc-600 scale-90 origin-left">LEV</span>
|
||||
<span className="text-zinc-300 font-bold">{strategy.config.risk_control.btc_eth_max_leverage || '-'}x</span>
|
||||
<span className="text-zinc-600 scale-90 origin-left">
|
||||
LEV
|
||||
</span>
|
||||
<span className="text-zinc-300 font-bold">
|
||||
{strategy.config.risk_control
|
||||
.btc_eth_max_leverage || '-'}
|
||||
x
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-zinc-600 scale-90 origin-left">POS</span>
|
||||
<span className="text-zinc-300 font-bold">{strategy.config.risk_control.max_positions || '-'}</span>
|
||||
<span className="text-zinc-600 scale-90 origin-left">
|
||||
POS
|
||||
</span>
|
||||
<span className="text-zinc-300 font-bold">
|
||||
{strategy.config.risk_control
|
||||
.max_positions || '-'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<Activity size={12} className="text-zinc-700" />
|
||||
<Activity
|
||||
size={12}
|
||||
className="text-zinc-700"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full text-zinc-600">
|
||||
<EyeOff size={16} className="mb-1 opacity-50" />
|
||||
<span className="text-[9px] uppercase tracking-widest">{tr('configHiddenDesc')}</span>
|
||||
<span className="text-[9px] uppercase tracking-widest">
|
||||
{tr('configHiddenDesc')}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -403,7 +489,9 @@ export function StrategyMarketPage() {
|
||||
{copiedId === strategy.id ? (
|
||||
<>
|
||||
<Check className="w-3 h-3 text-emerald-500" />
|
||||
<span className="text-emerald-500">{tr('copied')}</span>
|
||||
<span className="text-emerald-500">
|
||||
{tr('copied')}
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
@@ -413,13 +501,15 @@ export function StrategyMarketPage() {
|
||||
)}
|
||||
</button>
|
||||
) : (
|
||||
<button disabled className="w-full py-2.5 text-[10px] font-bold font-mono uppercase tracking-widest border border-zinc-800 bg-black text-zinc-700 cursor-not-allowed flex items-center justify-center gap-2">
|
||||
<button
|
||||
disabled
|
||||
className="w-full py-2.5 text-[10px] font-bold font-mono uppercase tracking-widest border border-zinc-800 bg-black text-zinc-700 cursor-not-allowed flex items-center justify-center gap-2"
|
||||
>
|
||||
<Shield size={12} />
|
||||
{tr('hideConfig')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</motion.div>
|
||||
)
|
||||
@@ -436,13 +526,23 @@ export function StrategyMarketPage() {
|
||||
transition={{ delay: 0.3 }}
|
||||
className="mt-16 mb-20 flex justify-center"
|
||||
>
|
||||
<div className="relative group cursor-pointer" onClick={() => window.location.href = '/strategy'}>
|
||||
<div
|
||||
className="relative group cursor-pointer"
|
||||
onClick={() => navigate('/strategy')}
|
||||
>
|
||||
<div className="absolute -inset-1 bg-gradient-to-r from-nofx-gold to-yellow-600 rounded blur opacity-25 group-hover:opacity-75 transition duration-1000 group-hover:duration-200"></div>
|
||||
<div className="relative px-8 py-4 bg-black border border-zinc-800 hover:border-nofx-gold/50 flex items-center gap-4 transition-all">
|
||||
<Hexagon className="text-nofx-gold animate-spin-slow" size={24} />
|
||||
<Hexagon
|
||||
className="text-nofx-gold animate-spin-slow"
|
||||
size={24}
|
||||
/>
|
||||
<div className="text-left">
|
||||
<div className="text-sm font-bold text-white uppercase tracking-wider group-hover:text-nofx-gold transition-colors">{tr('shareYours')}</div>
|
||||
<div className="text-[10px] text-zinc-500 font-mono">CONTRIBUTE TO THE GLOBAL DATABASE</div>
|
||||
<div className="text-sm font-bold text-white uppercase tracking-wider group-hover:text-nofx-gold transition-colors">
|
||||
{tr('shareYours')}
|
||||
</div>
|
||||
<div className="text-[10px] text-zinc-500 font-mono">
|
||||
CONTRIBUTE TO THE GLOBAL DATABASE
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-[1px] h-8 bg-zinc-800 mx-2"></div>
|
||||
<div className="text-xs font-mono text-zinc-400 group-hover:translate-x-1 transition-transform">
|
||||
@@ -452,7 +552,6 @@ export function StrategyMarketPage() {
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</DeepVoidBackground>
|
||||
|
||||
Reference in New Issue
Block a user