diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx new file mode 100644 index 0000000..8ade345 --- /dev/null +++ b/client/src/pages/Home.tsx @@ -0,0 +1,1409 @@ +// NAC XIC Token Presale — Main Page v3.0 +// Features: Real on-chain data | Bilingual (EN/ZH) | TRC20 Live Feed | Wallet Connect +// Design: Dark Cyberpunk / Quantum Finance +// Colors: Amber Gold #f0b429 | Quantum Blue #00d4ff | Deep Black #0a0a0f + +import { useState, useEffect, useCallback, useRef, useMemo } from "react"; +import { toast } from "sonner"; +import { Link } from "wouter"; +import { useWallet } from "@/hooks/useWallet"; +import { usePresale } from "@/hooks/usePresale"; +import { CONTRACTS, PRESALE_CONFIG, formatNumber, shortenAddress } from "@/lib/contracts"; +import { trpc } from "@/lib/trpc"; +import { type Lang, useTranslation } from "@/lib/i18n"; +import { WalletSelector } from "@/components/WalletSelector"; + +// ─── Network Tab Types ──────────────────────────────────────────────────────── +type NetworkTab = "BSC" | "ETH" | "TRON"; + +// ─── Assets ─────────────────────────────────────────────────────────────────── +const HERO_BG = "https://d2xsxph8kpxj0f.cloudfront.net/310519663287655625/Ngki3MumDNGduV3xJt3mga/nac-hero-bg_7c6c173e.jpg"; +const TOKEN_ICON = "https://d2xsxph8kpxj0f.cloudfront.net/310519663287655625/Ngki3MumDNGduV3xJt3mga/nac-token-icon_382e5c30.png"; + +// ─── Fallback stats while loading ───────────────────────────────────────────── +const FALLBACK_STATS = { + totalUsdtRaised: 0, + totalTokensSold: 0, + hardCap: 5_000_000, + progressPct: 0, +}; + +// ─── Countdown Timer ────────────────────────────────────────────────────────── +function useCountdown(targetDate: Date) { + const [timeLeft, setTimeLeft] = useState({ days: 0, hours: 0, minutes: 0, seconds: 0 }); + useEffect(() => { + const tick = () => { + const diff = targetDate.getTime() - Date.now(); + if (diff <= 0) { setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 }); return; } + setTimeLeft({ + days: Math.floor(diff / 86400000), + hours: Math.floor((diff % 86400000) / 3600000), + minutes: Math.floor((diff % 3600000) / 60000), + seconds: Math.floor((diff % 60000) / 1000), + }); + }; + tick(); + const id = setInterval(tick, 1000); + return () => clearInterval(id); + }, [targetDate]); + return timeLeft; +} + +// ─── Animated Counter ───────────────────────────────────────────────────────── +function AnimatedCounter({ value, prefix = "", suffix = "" }: { value: number; prefix?: string; suffix?: string }) { + const [display, setDisplay] = useState(0); + useEffect(() => { + if (value === 0) return; + let start = 0; + const step = value / 60; + const id = setInterval(() => { + start += step; + if (start >= value) { setDisplay(value); clearInterval(id); } + else setDisplay(Math.floor(start)); + }, 16); + return () => clearInterval(id); + }, [value]); + return {prefix}{display.toLocaleString()}{suffix}; +} + +// ─── Network Icon ───────────────────────────────────────────────────────────── +function NetworkIcon({ network }: { network: NetworkTab }) { + if (network === "BSC") return ( + + + + + + + + + ); + if (network === "ETH") return ( + + + + + + ); + return ( + + + + + + ); +} + +// ─── Step Badge ─────────────────────────────────────────────────────────────── +function StepBadge({ num, text }: { num: number; text: string }) { + return ( +
+
{num}
+ {text} +
+ ); +} + +// ─── TRC20 Purchase Panel ───────────────────────────────────────────────────── +function TRC20Panel({ usdtAmount, lang, connectedAddress, onConnectWallet }: { usdtAmount: number; lang: Lang; connectedAddress?: string; onConnectWallet?: () => void }) { + const { t } = useTranslation(lang); + const tokenAmount = usdtAmount / PRESALE_CONFIG.tokenPrice; + const [copied, setCopied] = useState(false); + const [evmAddress, setEvmAddress] = useState(connectedAddress || ""); + const [evmAddrError, setEvmAddrError] = useState(""); + const [submitted, setSubmitted] = useState(false); + // TronLink detection state — now handled by WalletSelector(showTron=true) + const [tronAddress, setTronAddress] = useState(null); + + // Auto-fill EVM address whenever wallet connects or address changes (unless user already submitted) + useEffect(() => { + if (connectedAddress && !submitted) { + setEvmAddress(connectedAddress); + } + }, [connectedAddress, submitted]); + + const submitTrc20Mutation = trpc.presale.registerTrc20Intent.useMutation({ + onSuccess: () => { + setSubmitted(true); + toast.success(lang === "zh" ? "XIC接收地址已保存!" : "XIC receiving address saved!"); + }, + onError: (err: { message: string }) => { + toast.error(err.message); + }, + }); + + const copyAddress = () => { + navigator.clipboard.writeText(CONTRACTS.TRON.receivingWallet); + setCopied(true); + toast.success(lang === "zh" ? "地址已复制到剪贴板!" : "Address copied to clipboard!"); + setTimeout(() => setCopied(false), 2000); + }; + + const validateEvmAddress = (addr: string) => { + if (!addr) return lang === "zh" ? "请输入您的XIC接收地址" : "Please enter your XIC receiving address"; + if (!/^0x[0-9a-fA-F]{40}$/.test(addr)) return lang === "zh" ? "无效的XIC接收地址格式(应以0x开头,入42位)" : "Invalid XIC receiving address format (must start with 0x, 42 chars)"; + return ""; + }; + + const handleEvmSubmit = () => { + const err = validateEvmAddress(evmAddress); + if (err) { setEvmAddrError(err); return; } + setEvmAddrError(""); + submitTrc20Mutation.mutate({ evmAddress }); + }; + + return ( +
+ {/* EVM Address Input — Required for token distribution */} +
+
+ ⚠️ +

+ {lang === "zh" ? "必填:您的XIC接收地址(BSC/ETH钉包地址)" : "Required: Your XIC Receiving Address (BSC/ETH wallet address)"} +

+
+

+ {lang === "zh" + ? "XIC代币将发放到您的BSC/ETH钉包地址(0x开头)。请确保填写正确的地址,否则无法收到代币。" + : "XIC tokens will be sent to your BSC/ETH wallet address (starts with 0x). Please make sure to enter the correct address."} +

+
+ {/* WalletSelector — shown when address not yet filled */} + {!evmAddress && !submitted && ( + { + setEvmAddress(addr); + setEvmAddrError(""); + toast.success(lang === "zh" ? "XIC接收地址已自动填充!" : "XIC receiving address auto-filled!"); + if (onConnectWallet) onConnectWallet(); + }} + /> + )} + { setEvmAddress(e.target.value); setEvmAddrError(""); setSubmitted(false); }} + placeholder={lang === "zh" ? "0x... (您的XIC接收地址)" : "0x... (your XIC receiving address)"} + className="w-full px-4 py-3 rounded-xl text-sm font-mono" + style={{ + background: "rgba(255,255,255,0.05)", + border: evmAddrError ? "1px solid rgba(255,82,82,0.5)" : submitted ? "1px solid rgba(0,230,118,0.4)" : "1px solid rgba(255,255,255,0.12)", + color: "white", + outline: "none", + }} + /> + {evmAddrError &&

{evmAddrError}

} + {submitted &&

✓ {lang === "zh" ? "XIC接收地址已保存" : "XIC receiving address saved"}

} + +
+
+ + {/* TronLink Wallet Detection — using unified WalletSelector with showTron=true */} +
+
+ + + + + +

+ {lang === "zh" ? "连接 TronLink 钱包(可选)" : "Connect TronLink Wallet (Optional)"} +

+
+ {tronAddress ? ( +
+

+ {lang === "zh" ? "已连接 TronLink 地址:" : "Connected TronLink address:"} +

+
+ ✓ {tronAddress} +
+

+ {lang === "zh" + ? "您的 TronLink 已连接。请在上方填写 XIC 接收地址,然后向下方地址发送 USDT。" + : "TronLink connected. Please fill your XIC receiving address above, then send USDT to the address below."} +

+
+ ) : ( +
+

+ {lang === "zh" + ? "连接 TronLink 可自动验证您的 TRON 地址。手机用户可通过 TronLink App 内置浏览器打开本页面。" + : "Connect TronLink to auto-verify your TRON address. Mobile users can open this page in TronLink App's built-in browser."} +

+ { + if (network === "tron") { + setTronAddress(addr); + toast.success(lang === "zh" ? "TronLink 已连接!" : "TronLink connected!"); + } else { + // EVM address detected in TRC20 panel — use as XIC receiving address + setEvmAddress(addr); + setEvmAddrError(""); + toast.success(lang === "zh" ? "XIC接收地址已自动填充!" : "XIC receiving address auto-filled!"); + if (onConnectWallet) onConnectWallet(); + } + }} + /> +
+ )} +
+ +
+

{t("trc20_send_to")}

+
+ {CONTRACTS.TRON.receivingWallet} +
+ +
+ +
+ + 0 ? usdtAmount.toFixed(2) + " USDT" : "任意数量 USDT"}(TRC20)到上方地址` + : `${t("trc20_step1")} ${usdtAmount > 0 ? usdtAmount.toFixed(2) + " USDT" : t("trc20_step1_any")} (TRC20) ${t("trc20_step1b")}` + } /> + + 0 ? `${t("trc20_step3")} ${formatNumber(tokenAmount)} ${t("trc20_step3b")}` : t("trc20_step3_any")) + : (usdtAmount > 0 ? `You will receive ${formatNumber(tokenAmount)} XIC tokens after confirmation (1-24h)` : t("trc20_step3_any")) + } /> + +
+ +
+ {t("trc20_warning")} +
+
+ ); +} + +// ─── EVM Purchase Panel ───────────────────────────────────────────────────── +function EVMPurchasePanel({ network, lang, wallet }: { network: "BSC" | "ETH"; lang: Lang; wallet: WalletHookReturn }) { + const { t } = useTranslation(lang); + const { purchaseState, buyWithUSDT, reset, calcTokens, getUsdtBalance } = usePresale(wallet, network); + const [usdtInput, setUsdtInput] = useState("100"); + const [usdtBalance, setUsdtBalance] = useState(null); + const [manualAddress, setManualAddress] = useState(null); + const targetChainId = CONTRACTS[network].chainId; + const isWrongNetwork = wallet.isConnected && wallet.chainId !== targetChainId; + // effectiveAddress: 真实钱包地址 或 手动输入的地址 + const effectiveAddress = wallet.address || manualAddress; + const isManualMode = !wallet.isConnected && !!manualAddress; + + const fetchBalance = useCallback(async () => { + const bal = await getUsdtBalance(); + setUsdtBalance(bal); + }, [getUsdtBalance]); + + useEffect(() => { + if (wallet.isConnected) fetchBalance(); + }, [wallet.isConnected, fetchBalance]); + + const usdtAmount = parseFloat(usdtInput) || 0; + const tokenAmount = calcTokens(usdtAmount); + // maxPurchaseUSDT=0 means no limit; otherwise check against the limit + const isValidAmount = usdtAmount > 0 && (PRESALE_CONFIG.maxPurchaseUSDT === 0 || usdtAmount <= PRESALE_CONFIG.maxPurchaseUSDT); + + const handleBuy = async () => { + if (!isValidAmount) { + toast.error(lang === "zh" + ? `请输入有效金额(最大 $${PRESALE_CONFIG.maxPurchaseUSDT.toLocaleString()} USDT)` + : `Please enter a valid amount (max $${PRESALE_CONFIG.maxPurchaseUSDT.toLocaleString()} USDT)`); + return; + } + await buyWithUSDT(usdtAmount); + }; + + useEffect(() => { + if (purchaseState.step === "success") { + toast.success(lang === "zh" + ? `购买成功!获得 ${formatNumber(purchaseState.tokenAmount)} 枚 XIC 代币!` + : `Successfully purchased ${formatNumber(purchaseState.tokenAmount)} XIC tokens!`); + } else if (purchaseState.step === "error" && purchaseState.error) { + toast.error(purchaseState.error.slice(0, 120)); + } + }, [purchaseState.step, purchaseState.error, purchaseState.tokenAmount, lang]); + + if (purchaseState.step === "success") { + return ( +
+
🎉
+

+ {t("buy_success_title")} +

+

+ {t("buy_success_msg")} {formatNumber(purchaseState.tokenAmount)} {t("buy_success_tokens")} +

+ {purchaseState.txHash && ( + + {t("buy_view_explorer")} + + )} + +
+ ); + } + + const isProcessing = ["approving", "approved", "purchasing"].includes(purchaseState.step); + + return ( +
+ {/* Wallet info — shown when connected or manual address entered */} + {effectiveAddress && !isWrongNetwork && ( +
+
+
+ {shortenAddress(effectiveAddress)} + {isManualMode && {lang === "zh" ? "(手动地址)" : "(manual)"}} +
+ {usdtBalance !== null && !isManualMode && ( + {t("buy_balance")} {usdtBalance.toFixed(2)} USDT + )} +
+ )} + {/* Wrong network banner */} + {isWrongNetwork && ( +
+
⚠️
+

{t("buy_wrong_network")}

+

{t("buy_wrong_msg")} {CONTRACTS[network].chainName}

+ +
+ )} + + {/* USDT Amount Input */} +
+ +
+ setUsdtInput(e.target.value)} + min={0} + max={PRESALE_CONFIG.maxPurchaseUSDT} + placeholder={t("buy_placeholder")} + className="input-nac w-full px-4 py-3 rounded-xl text-lg counter-digit pr-20" + disabled={isProcessing} + /> + USDT +
+
+ {[100, 500, 1000, 5000].map(amt => ( + + ))} +
+
+ + {/* Token Amount Preview */} +
+
+ {t("buy_you_receive")} +
+ + {formatNumber(tokenAmount)} + + XIC +
+
+
+ {t("buy_price_per")} + $0.02 USDT +
+
+ + {/* Purchase Steps — Transfer Mode */} + {(purchaseState.step === "sending" || purchaseState.step === "success") && ( +
+
+
+ {purchaseState.step === "success" && } +
+ {lang === "zh" ? "正在发送 USDT 到接收钱包..." : "Sending USDT to receiving wallet..."} +
+ {purchaseState.txHash && ( + + )} +
+ )} + + {/* Buy Button — or Connect Wallet if not connected */} + {!wallet.isConnected && !manualAddress ? ( +
+

{t("buy_connect_msg")}

+ { + setManualAddress(addr); + toast.success(lang === "zh" ? `地址已确认: ${addr.slice(0, 6)}...${addr.slice(-4)}` : `Address confirmed: ${addr.slice(0, 6)}...${addr.slice(-4)}`); + }} + compact + /> +
{t("buy_connect_hint")}
+
+ ) : isWrongNetwork ? ( + + ) : isManualMode ? ( +
+
+

+ {lang === "zh" ? "⚠️ 手动地址模式:需连接钱包才能完成链上购买" : "⚠️ Manual mode: Connect wallet to complete on-chain purchase"} +

+

+ {lang === "zh" ? "请点击右上角连接您的钱包" : "Please connect your wallet via the top-right button"} +

+
+ +
+ ) : ( + + )} + +

+ {PRESALE_CONFIG.maxPurchaseUSDT > 0 + ? `${t("buy_no_min_max")} $${PRESALE_CONFIG.maxPurchaseUSDT.toLocaleString()} USDT` + : (lang === "zh" ? "无最低/最高购买限制" : "No minimum or maximum purchase limit")} +

+ + {/* Add XIC to Wallet button — only show on BSC where token address is known */} + {network === "BSC" && CONTRACTS.BSC.token && ( + + )} +
+ ); +} + +// ─── FAQ Item ───────────────────────────────────────────────────────────────── +function FAQItem({ q, a, index }: { q: string; a: string; index: number }) { + const [open, setOpen] = useState(false); + return ( +
+ + {open && ( +
+
+

{a}

+
+
+ )} +
+ ); +} + +// ─── Purchase Feed ──────────────────────────────────────────────────────────── +function PurchaseFeed({ lang }: { lang: Lang }) { + const { t } = useTranslation(lang); + const feedRef = useRef(null); + + // Fetch real TRC20 purchases from backend + const { data: trc20Records } = trpc.presale.recentPurchases.useQuery( + { limit: 20 }, + { refetchInterval: 30_000 } + ); + + // Merge real TRC20 with mock EVM records for display + const [records, setRecords] = useState>([ + { address: "0x3a4f...8c2d", amount: 250000, usdt: 5000, time: "2 min ago", chain: "BSC" }, + { address: "0x7b1e...f93a", amount: 50000, usdt: 1000, time: "5 min ago", chain: "ETH" }, + { address: "TRX9k...m4pQ", amount: 125000, usdt: 2500, time: "8 min ago", chain: "TRON" }, + { address: "0xd92c...1a7f", amount: 500000, usdt: 10000, time: "12 min ago", chain: "BSC" }, + { address: "0x5e8b...c3d1", amount: 25000, usdt: 500, time: "15 min ago", chain: "ETH" }, + { address: "TRX2m...k9nL", amount: 75000, usdt: 1500, time: "19 min ago", chain: "TRON" }, + ]); + + // Inject real TRC20 records at the top + useEffect(() => { + if (!trc20Records || trc20Records.length === 0) return; + const realRecords = trc20Records.slice(0, 5).map(r => ({ + address: r.fromAddress.slice(0, 6) + "..." + r.fromAddress.slice(-4), + amount: r.xicAmount, + usdt: r.usdtAmount, + time: new Date(r.createdAt).toLocaleTimeString(), + chain: "TRON", + isReal: true, + })); + setRecords(prev => { + const merged = [...realRecords, ...prev.filter(p => !p.isReal)]; + return merged.slice(0, 10); + }); + }, [trc20Records]); + + // Simulate new EVM purchases every 18-30 seconds + useEffect(() => { + const names = ["0x2f4a...8e1c", "0x9b3d...7f2a", "TRXab...c5mN", "0x1e7c...4d9b", "0x8a2f...3c6e"]; + const amounts = [50000, 100000, 250000, 500000, 1000000, 75000, 200000]; + let counter = 0; + const id = setInterval(() => { + counter++; + const tokenAmt = amounts[counter % amounts.length]; + const usdtAmt = tokenAmt * 0.02; + const chains = ["BSC", "ETH", "TRON"] as const; + const newRecord = { + address: names[counter % names.length], + amount: tokenAmt, + usdt: usdtAmt, + time: lang === "zh" ? "刚刚" : "just now", + chain: chains[counter % 3], + }; + setRecords(prev => [newRecord, ...prev.slice(0, 9)]); + }, 18000 + Math.random() * 12000); + return () => clearInterval(id); + }, [lang]); + + const chainColor = (chain: string) => { + if (chain === "BSC") return "#F0B90B"; + if (chain === "ETH") return "#627EEA"; + return "#FF0013"; + }; + + return ( +
+
+

{t("stats_live_feed")}

+
+ + {t("stats_live")} +
+
+
+ {records.map((r, i) => ( +
+
+ + {r.chain} + + {r.address} + {r.isReal && } +
+
+
+ +{formatNumber(r.amount)} XIC +
+
{r.time}
+
+
+ ))} +
+
+ ); +} + +// ─── Chat Support Widget ────────────────────────────────────────────────────── +function ChatSupport({ lang }: { lang: Lang }) { + const { t } = useTranslation(lang); + const [open, setOpen] = useState(false); + + return ( +
+ {open && ( +
+
+
+
+ 💬 +
+
+
{t("support_title")}
+
+ + {t("support_online")} +
+
+
+ +
+
+

{t("support_msg")}

+
+ +

{t("support_response")}

+
+ )} + +
+ ); +} + +// ─── Navbar Wallet Button ───────────────────────────────────────────────────── +type WalletHookReturn = ReturnType; +function NavWalletButton({ lang, wallet }: { lang: Lang; wallet: WalletHookReturn }) { + const { t } = useTranslation(lang); + const [showMenu, setShowMenu] = useState(false); + const [showWalletModal, setShowWalletModal] = useState(false); + const menuRef = useRef(null); + + useEffect(() => { + const handleClick = (e: MouseEvent) => { + if (menuRef.current && !menuRef.current.contains(e.target as Node)) setShowMenu(false); + }; + document.addEventListener("mousedown", handleClick); + return () => document.removeEventListener("mousedown", handleClick); + }, []); + + // Detect mobile browser + const isMobile = typeof window !== "undefined" && /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + + // Handle connect button click — show wallet selector modal + const handleConnectClick = async () => { + // On mobile browsers, skip direct connect attempt and show modal immediately + // (mobile browsers don't support wallet extensions) + if (isMobile) { + setShowWalletModal(true); + return; + } + // On desktop: first try direct connect (works if wallet is already set up and locked) + const result = await wallet.connect(); + if (!result.success && result.error) { + // If direct connect failed, show the wallet selector modal for guided setup + setShowWalletModal(true); + toast.error(result.error, { duration: 6000 }); + } + }; + + if (!wallet.isConnected) { + return ( + <> + + + {/* Wallet Connection Modal */} + {showWalletModal && ( +
{ if (e.target === e.currentTarget) setShowWalletModal(false); }} + > +
+ {/* Close button */} + + +

+ {lang === "zh" ? "连接钱包" : "Connect Wallet"} +

+

+ {lang === "zh" + ? "选择您的钱包进行连接,或手动输入地址" + : "Select your wallet to connect, or enter address manually"} +

+ + {/* MetaMask initialization guide */} +
+

+ {lang === "zh" + ? "💡 首次使用 MetaMask?请先打开 MetaMask 扩展完成初始化(创建或导入钱包),完成后点击下方「刷新」按钮重新检测。" + : "💡 First time using MetaMask? Open the MetaMask extension and complete setup (create or import a wallet), then click Refresh below to re-detect."} +

+
+ + { + // After address detected from WalletSelector, sync wallet state + const result = await wallet.connect(); + if (result.success) { + setShowWalletModal(false); + toast.success(lang === "zh" ? `钱包已连接: ${addr.slice(0, 6)}...${addr.slice(-4)}` : `Wallet connected: ${addr.slice(0, 6)}...${addr.slice(-4)}`); + } else { + // Even if connect() failed, we have the address — close modal + setShowWalletModal(false); + toast.success(lang === "zh" ? `地址已确认: ${addr.slice(0, 6)}...${addr.slice(-4)}` : `Address confirmed: ${addr.slice(0, 6)}...${addr.slice(-4)}`); + } + }} + /> +
+
+ )} + + ); + } + + return ( +
+ + {showMenu && ( +
+
+

{t("nav_connected")}

+

{wallet.shortAddress}

+
+ +
+ )} +
+ ); +} + +// ─── Language Toggle ────────────────────────────────────────────────────────── +function LangToggle({ lang, setLang }: { lang: Lang; setLang: (l: Lang) => void }) { + return ( +
+ +
+ +
+ ); +} + +// ─── Main Page ──────────────────────────────────────────────────────────────── +export default function Home() { + const [lang, setLang] = useState(() => { + // Auto-detect browser language + const browserLang = navigator.language.toLowerCase(); + return browserLang.startsWith("zh") ? "zh" : "en"; + }); + const { t, faq } = useTranslation(lang); + + const [activeNetwork, setActiveNetwork] = useState("BSC"); + const [trcUsdtAmount, setTrcUsdtAmount] = useState("100"); + // useMemo stabilizes the Date reference to prevent infinite re-renders in useCountdown + const presaleEndDate = useMemo(() => new Date("2026-06-30T23:59:59Z"), []); + const countdown = useCountdown(presaleEndDate); + + // ── Real on-chain stats ── + const { data: onChainStats, isLoading: statsLoading } = trpc.presale.stats.useQuery(undefined, { + refetchInterval: 60_000, // Refresh every 60 seconds + staleTime: 30_000, + }); + + const stats = onChainStats || FALLBACK_STATS; + const progressPct = stats.progressPct || 0; + // Presale active/paused status from backend config + const isPresalePaused = (onChainStats as any)?.presaleStatus === "paused"; + + // 钱包状态提升到顶层,共享给NavWalletButton和EVMPurchasePanel + const wallet = useWallet(); + + const networks: NetworkTab[] = ["BSC", "ETH", "TRON"]; + + return ( +
+ {/* ── Presale Paused Banner ── */} + {isPresalePaused && ( +
+ + {lang === "zh" ? "预售活动已暂停,暂时无法购买。请关注官方渠道获取最新公告。" : "Presale is currently paused. Please follow our official channels for updates."} + +
+ )} + {/* ── Navigation ── */} + + + {/* ── Hero Section ── */} +
+
+
+
+
+ + {t("hero_badge")} +
+

+ {t("hero_title")} +

+

{t("hero_subtitle")}

+
+ {t("hero_price")} + {t("hero_supply")} + {t("hero_networks")} + {t("hero_no_min")} +
+
+
+ + {/* ── Main Content ── */} +
+
+ + {/* ── Left Panel: Stats & Info ── */} +
+ + {/* Countdown */} +
+

{t("stats_ends_in")}

+
+ {[ + { label: t("stats_days"), value: countdown.days }, + { label: t("stats_hours"), value: countdown.hours }, + { label: t("stats_mins"), value: countdown.minutes }, + { label: t("stats_secs"), value: countdown.seconds }, + ].map(({ label, value }) => ( +
+
+ {String(value).padStart(2, "0")} +
+
{label}
+
+ ))} +
+
+ + {/* Progress — Real On-Chain Data */} +
+
+

{t("stats_raised")}

+
+ {statsLoading ? ( + {t("loading_stats")} + ) : ( + <> + + {t("stats_live_data")} + + )} + {progressPct.toFixed(1)}% +
+
+
+
+
+
+
+
+ +
+
{t("stats_raised_label")}
+
+
+
+ ${formatNumber(stats.hardCap)} +
+
{t("stats_hard_cap")}
+
+
+
+ + {/* Stats Grid */} +
+ {[ + { label: t("stats_tokens_sold"), value: formatNumber(stats.totalTokensSold), unit: "XIC" }, + { label: t("stats_token_price"), value: "$0.02", unit: "USDT" }, + { label: t("stats_listing"), value: "$0.10", unit: t("stats_target") }, + { label: t("hero_networks"), value: "3", unit: "BSC · ETH · TRC20" }, + ].map(({ label, value, unit }) => ( +
+
{value}
+
{label}
+
{unit}
+
+ ))} +
+ + {/* Token Info */} +
+

{t("token_details")}

+ {[ + { label: t("token_name"), value: "New AssetChain Token" }, + { label: t("token_symbol"), value: "XIC" }, + { label: t("token_network"), value: "BSC (BEP-20)" }, + { label: t("token_decimals"), value: "18" }, + { label: t("token_supply"), value: "100,000,000,000" }, + ].map(({ label, value }) => ( +
+ {label} + {value} +
+ ))} + + {t("token_view_contract")} + +
+ + {/* Live Purchase Feed */} + +
+ + {/* ── Right Panel: Purchase ── */} +
+
+ {/* Token Icon + Title */} +
+ XIC +
+

{t("buy_title")}

+

{t("buy_subtitle")} $0.02 USDT · {t("buy_no_min")}

+
+
+ + {/* Network Selector */} +
+

{t("buy_select_network")}

+
+ {networks.map(net => ( + + ))} +
+
+ + {/* Purchase Area */} +
+ {/* Presale Paused Overlay */} + {isPresalePaused && ( +
+
+

+ {lang === "zh" ? "预售已暂停" : "Presale Paused"} +

+

+ {lang === "zh" ? "请关注官方 Telegram / Twitter 获取最新公告" : "Follow our official Telegram / Twitter for updates"} +

+
+ )} + {activeNetwork === "BSC" && } + {activeNetwork === "ETH" && } + {activeNetwork === "TRON" && ( +
+
+ +
+ setTrcUsdtAmount(e.target.value)} + placeholder={t("buy_placeholder")} + className="input-nac w-full px-4 py-3 rounded-xl text-lg counter-digit pr-20" + /> + USDT +
+
+ {[100, 500, 1000, 5000].map(amt => ( + + ))} +
+
+ +
+ )} +
+ + {/* Presale Contract Links */} + +
+ + {/* Why NAC */} +
+ {[ + { icon: "🔗", title: t("why_rwa_title"), desc: t("why_rwa_desc") }, + { icon: "⚡", title: t("why_cbpp_title"), desc: t("why_cbpp_desc") }, + { icon: "🛡️", title: t("why_charter_title"), desc: t("why_charter_desc") }, + ].map(({ icon, title, desc }) => ( +
+
{icon}
+

{title}

+

{desc}

+
+ ))} +
+
+
+
+ + {/* ── FAQ Section ── */} +
+
+

+ {t("faq_title")} +

+

{t("faq_subtitle")}

+
+
+ {faq.map((item, i) => ( + + ))} +
+
+

{t("faq_still")}

+ + + + + {t("faq_ask")} + +
+
+ + {/* ── Footer ── */} +
+
+ XIC + New AssetChain +
+

{t("footer_risk")}

+
+ {[ + { label: t("footer_website"), href: "https://newassetchain.io" }, + { label: t("footer_explorer"), href: "https://lens.newassetchain.io" }, + { label: t("footer_telegram"), href: "https://t.me/newassetchain" }, + { label: t("footer_twitter"), href: "https://twitter.com/newassetchain" }, + ].map(({ label, href }) => ( + + {label} + + ))} +
+
+ + {/* ── Chat Support Widget ── */} + + + +
+ ); +}