diff --git a/502.html b/502.html index a45ef36..19d9e4d 100644 --- a/502.html +++ b/502.html @@ -129,8 +129,8 @@

The application is currently launching. The page will automatically refresh once site is available.

-

AI App Draft

-

Crypto trading platform inspired by OKX with exchange, wallets, orders, and KYC.

+

ADML Exchange

+

Professional crypto trading platform with spot, perpetual contracts, and second contracts.

App Logo - \ No newline at end of file + diff --git a/assets/pasted-20260125-132149-bf76a614.png b/assets/pasted-20260125-132149-bf76a614.png new file mode 100644 index 0000000..7663d74 Binary files /dev/null and b/assets/pasted-20260125-132149-bf76a614.png differ diff --git a/assets/pasted-20260125-140107-3b747574.png b/assets/pasted-20260125-140107-3b747574.png new file mode 100644 index 0000000..18affe9 Binary files /dev/null and b/assets/pasted-20260125-140107-3b747574.png differ diff --git a/backend/src/config.js b/backend/src/config.js index 3cb1d63..dbeeaab 100644 --- a/backend/src/config.js +++ b/backend/src/config.js @@ -1,6 +1,3 @@ - - - const os = require('os'); const config = { @@ -39,7 +36,7 @@ const config = { }, uploadDir: os.tmpdir(), email: { - from: 'AI App Draft ', + from: 'ADML Exchange ', host: 'email-smtp.us-east-1.amazonaws.com', port: 587, auth: { @@ -76,4 +73,4 @@ config.swaggerUrl = `${config.swaggerUI}${config.swaggerPort}`; config.uiUrl = `${config.hostUI}${config.portUI ? `:${config.portUI}` : ``}/#`; config.backUrl = `${config.hostUI}${config.portUI ? `:${config.portUI}` : ``}`; -module.exports = config; +module.exports = config; \ No newline at end of file diff --git a/frontend/next.config.mjs b/frontend/next.config.mjs index 89767ec..ba66881 100644 --- a/frontend/next.config.mjs +++ b/frontend/next.config.mjs @@ -2,11 +2,9 @@ * @type {import('next').NextConfig} */ -const output = process.env.NODE_ENV === 'production' ? 'export' : 'standalone'; - const nextConfig = { -trailingSlash: true, +const nextConfig = { + trailingSlash: true, distDir: 'build', - output, basePath: "", devIndicators: { position: 'bottom-left', @@ -26,7 +24,6 @@ trailingSlash: true, }, ], }, - } export default nextConfig \ No newline at end of file diff --git a/frontend/public/locales/de/common.json b/frontend/public/locales/de/common.json index 7f2d578..1453fd2 100644 --- a/frontend/public/locales/de/common.json +++ b/frontend/public/locales/de/common.json @@ -2,54 +2,32 @@ "pages": { "dashboard": { "pageTitle": "Dashboard", - "overview": "Übersicht", + "overview": "ADML Exchange Übersicht", "loadingWidgets": "Widgets werden geladen...", - "loading": "Laden..." + "loading": "Wird geladen..." }, "login": { - "pageTitle": "Anmeldung", - - "sampleCredentialsAdmin": "Verwenden Sie {{email}} / {{password}}, um sich als Administrator anzumelden", - "sampleCredentialsUser": "Verwenden Sie {{email}} / {{password}}, um sich als Benutzer anzumelden", - + "pageTitle": "Login", "form": { - "loginLabel": "Login", - "loginHelp": "Bitte geben Sie Ihren Login ein", - "passwordLabel": "Passwort", - "passwordHelp": "Bitte geben Sie Ihr Passwort ein", - "remember": "Angemeldet bleiben", - "forgotPassword": "Passwort vergessen?", - "loginButton": "Anmelden", - "loading": "Wird geladen...", - "noAccountYet": "Noch kein Konto?", - "newAccount": "Neues Konto" - }, - - "pexels": { - "photoCredit": "Foto von {{photographer}} auf Pexels", - "videoCredit": "Video von {{name}} auf Pexels", - "videoUnsupported": "Ihr Browser unterstützt das Video-Tag nicht." - }, - - "footer": { - "copyright": "© {{year}} {{title}}. Alle Rechte vorbehalten", - "privacy": "Datenschutzrichtlinie" + "loginLabel": "Login", + "loginHelp": "Bitte geben Sie Ihren Login ein", + "passwordLabel": "Passwort", + "passwordHelp": "Bitte geben Sie Ihr Passwort ein", + "remember": "Angemeldet bleiben", + "forgotPassword": "Passwort vergessen?", + "loginButton": "Anmelden", + "loading": "Wird geladen...", + "noAccountYet": "Noch kein Konto?", + "newAccount": "Neues Konto registrieren" } - } - }, - "components": { - "widgetCreator": { - "title": "Diagramm oder Widget erstellen", - "helpText": "Beschreiben Sie Ihr neues Widget oder Diagramm in natürlicher Sprache. Zum Beispiel: \"Anzahl der Admin-Benutzer\" ODER \"rotes Diagramm mit der Anzahl geschlossener Verträge gruppiert nach Monat\"", - "settingsTitle": "Einstellungen für Widget Creator", - "settingsDescription": "Für welche Rolle zeigen wir Widgets an und erstellen sie?", - "doneButton": "Fertig", - "loading": "Laden..." }, - "search": { - "placeholder": "Suche", - "required": "Pflichtfeld", - "minLength": "Mindestlänge: {{count}} Zeichen" + "exchange": { + "pageTitle": "Spot-Handel", + "spot": "Spot", + "perpetual": "Perpetual", + "seconds": "Sekunden-Kontrakt", + "buy": "Kaufen", + "sell": "Verkaufen" } } -} +} \ No newline at end of file diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index 8d45685..6d5ef78 100644 --- a/frontend/public/locales/en/common.json +++ b/frontend/public/locales/en/common.json @@ -1,52 +1,176 @@ { - "pages": { - "dashboard": { - "pageTitle": "Dashboard", - "overview": "Overview", - "loadingWidgets": "Loading widgets...", - "loading": "Loading..." + "nav": { + "markets": "Markets", + "spot": "Spot", + "perpetual": "Perpetual", + "options": "Options" + }, + "landing": { + "hero": { + "title": "ADML Exchange | The World’s Leading Crypto Exchange", + "badge": "Trusted by 20M+ Users Globally", + "title_part1": "Trade The Future", + "title_highlight": "With ADML", + "subtitle": "Securely buy, sell and trade over 400+ cryptocurrencies with low fees and institutional-grade security.", + "input_placeholder": "Email / Phone number", + "cta": "Get Started" }, - "login": { - "pageTitle": "Login", - - "form": { - "loginLabel": "Login", - "loginHelp": "Please enter your login", - "passwordLabel": "Password", - "passwordHelp": "Please enter your password", - "remember": "Remember", - "forgotPassword": "Forgot password?", - "loginButton": "Login", - "loading": "Loading...", - "noAccountYet": "Don’t have an account yet?", - "newAccount": "New Account" + "stats": { + "24h_vol": "24h Volume", + "users": "Active Users", + "assets": "Assets Listed", + "uptime": "System Uptime" + }, + "features": { + "security": { + "title": "Security First", + "desc": "Cold storage, multi-sig wallets, and 2FA protection for all assets. Your security is our priority." }, - - "pexels": { - "photoCredit": "Photo by {{photographer}} on Pexels", - "videoCredit": "Video by {{name}} on Pexels", - "videoUnsupported": "Your browser does not support the video tag." + "speed": { + "title": "Instant Execution", + "desc": "Our high-performance matching engine handles 1M+ transactions per second with sub-millisecond latency." }, - - "footer": { - "copyright": "© {{year}} {{title}}. All rights reserved", - "privacy": "Privacy Policy" + "support": { + "title": "24/7 Support", + "desc": "Global customer support available in 12 languages around the clock to assist you with any issues." } + }, + "markets": { + "title": "Market Trends", + "tab": { + "popular": "Popular", + "new": "New Listings", + "gainers": "Top Gainers" + }, + "view_all": "View All Markets", + "col": { + "asset": "Asset", + "price": "Price", + "change": "24h Change", + "volume": "Volume", + "action": "Action" + }, + "trade_btn": "Trade" + }, + "app": { + "title": "Trade Anywhere, Anytime.", + "desc": "Stay connected to the markets with our professional mobile app. Available on iOS, Android, and Web.", + "qr_title": "Scan to download", + "qr_desc": "Instant access to ADML features on your mobile device." + }, + "cta": { + "title": "Start Your Trade Now", + "desc": "Join the most reliable crypto exchange in the world.", + "btn_signup": "Create Account", + "btn_login": "Login Demo" } }, - "components": { - "widgetCreator": { - "title": "Create Chart or Widget", - "helpText": "Describe your new widget or chart in natural language. For example: \"Number of admin users\" OR \"red chart with number of closed contracts grouped by month\"", - "settingsTitle": "Widget Creator Settings", - "settingsDescription": "What role are we showing and creating widgets for?", - "doneButton": "Done", - "loading": "Loading..." + "exchange": { + "title": "Spot Trading", + "header": { + "spot": "Spot", + "last_price": "Last Price", + "change": "24h Change", + "high": "24h High", + "low": "24h Low", + "volume": "24h Volume", + "deposit": "Deposit" }, - "search": { - "placeholder": "Search", - "required": "Required", - "minLength": "Minimum length: {{count}} characters" + "tabs": { + "open_orders": "Open Orders", + "order_history": "Order History", + "trade_history": "Trade History", + "assets": "Assets" + }, + "orderbook": { + "title": "Order Book", + "price": "Price", + "amount": "Amount" + }, + "panel": { + "buy": "Buy", + "sell": "Sell", + "type": "Order Type", + "market": "Market", + "price": "Price", + "amount": "Amount", + "available": "Available" + }, + "no_records": "No active records found" + }, + "perpetual": { + "title": "Perpetual Trading", + "header": { + "perp": "Perp", + "mark_price": "Mark Price", + "funding": "Funding / Countdown", + "change": "24h Change", + "margin": "Margin", + "cross": "Cross", + "deposit": "Deposit" + }, + "tabs": { + "positions": "Positions", + "open_orders": "Open Orders", + "order_history": "Order History", + "trade_history": "Trade History" + }, + "panel": { + "long": "Open Long", + "short": "Open Short", + "mode": "Margin Mode", + "cross": "Cross", + "price": "Price", + "amount": "Amount", + "leverage": "Adjust Leverage", + "available": "Available", + "max_long": "Max Long", + "buy": "BUY / LONG", + "sell": "SELL / SHORT" + }, + "orderbook": { + "title": "Market Depth" + }, + "no_positions": "No active positions or orders" + }, + "seconds": { + "title": "Binary Options", + "header": { + "contract": "Option Contract", + "current_price": "Current Price", + "yield": "Estimated Yield", + "balance": "Available Balance", + "deposit": "Deposit" + }, + "tabs": { + "current": "Current Positions", + "history": "Trade History" + }, + "panel": { + "period": "Execution Period", + "yield": "Yield", + "amount": "Investment Amount", + "expected_profit": "Expected Profit", + "call": "CALL (HIGH)", + "put": "PUT (LOW)", + "risk_warning": "Risk Warning: Trading involves significant risk of loss and is not suitable for all investors." + }, + "no_history": "No active contracts" + }, + "footer": { + "about": "Professional and secure digital asset trading platform.", + "section": { + "about": "About", + "product": "Product", + "support": "Support", + "legal": "Legal" } + }, + "login": { + "title": "Log in", + "demo_login": "Demo Account Login" + }, + "register": { + "title": "Sign up" } } diff --git a/frontend/public/locales/es/common.json b/frontend/public/locales/es/common.json index f3421b1..cb67077 100644 --- a/frontend/public/locales/es/common.json +++ b/frontend/public/locales/es/common.json @@ -1,55 +1,33 @@ { "pages": { "dashboard": { - "pageTitle": "Tablero", - "overview": "Resumen", + "pageTitle": "Panel de control", + "overview": "Resumen de ADML Exchange", "loadingWidgets": "Cargando widgets...", "loading": "Cargando..." }, "login": { - "pageTitle": "Inicio de sesión", - - "sampleCredentialsAdmin": "Use {{email}} / {{password}} para iniciar sesión como Administrador", - "sampleCredentialsUser": "Use {{email}} / {{password}} para iniciar sesión como Usuario", - + "pageTitle": "Iniciar sesión", "form": { - "loginLabel": "Usuario", - "loginHelp": "Introduzca su usuario", - "passwordLabel": "Contraseña", - "passwordHelp": "Introduzca su contraseña", - "remember": "Recuérdame", - "forgotPassword": "¿Olvidó su contraseña?", - "loginButton": "Acceder", - "loading": "Cargando...", - "noAccountYet": "¿Aún no tiene una cuenta?", - "newAccount": "Crear cuenta" - }, - - "pexels": { - "photoCredit": "Foto de {{photographer}} en Pexels", - "videoCredit": "Vídeo de {{name}} en Pexels", - "videoUnsupported": "Su navegador no admite la etiqueta de vídeo." - }, - - "footer": { - "copyright": "© {{year}} {{title}}. Todos los derechos reservados", - "privacy": "Política de privacidad" + "loginLabel": "Login", + "loginHelp": "Por favor, introduzca su login", + "passwordLabel": "Contraseña", + "passwordHelp": "Por favor, introduzca su contraseña", + "remember": "Recordarme", + "forgotPassword": "¿Olvidó su contraseña?", + "loginButton": "Entrar", + "loading": "Cargando...", + "noAccountYet": "¿No tiene cuenta?", + "newAccount": "Registrar nueva cuenta" } - } - }, - "components": { - "widgetCreator": { - "title": "Crear gráfico o widget", - "helpText": "Describe tu nuevo widget o gráfico en lenguaje natural. Por ejemplo: \"Número de usuarios administradores\" O \"gráfico rojo con el número de contratos cerrados agrupados por mes\"", - "settingsTitle": "Configuración del creador de widgets", - "settingsDescription": "¿Para qué rol estamos mostrando y creando widgets?", - "doneButton": "Listo", - "loading": "Cargando..." }, - "search": { - "placeholder": "Buscar", - "required": "Obligatorio", - "minLength": "Longitud mínima: {{count}} caracteres" + "exchange": { + "pageTitle": "Trading Spot", + "spot": "Spot", + "perpetual": "Perpetuo", + "seconds": "Contrato de segundos", + "buy": "Comprar", + "sell": "Vender" } } -} +} \ No newline at end of file diff --git a/frontend/public/locales/fr/common.json b/frontend/public/locales/fr/common.json index ecf531b..97274d1 100644 --- a/frontend/public/locales/fr/common.json +++ b/frontend/public/locales/fr/common.json @@ -2,54 +2,32 @@ "pages": { "dashboard": { "pageTitle": "Tableau de bord", - "overview": "Vue d'ensemble", + "overview": "Aperçu de ADML Exchange", "loadingWidgets": "Chargement des widgets...", "loading": "Chargement..." }, "login": { "pageTitle": "Connexion", - - "sampleCredentialsAdmin": "Utilisez {{email}} / {{password}} pour vous connecter en tant qu’administrateur", - "sampleCredentialsUser": "Utilisez {{email}} / {{password}} pour vous connecter en tant qu’utilisateur", - "form": { - "loginLabel": "Identifiant", - "loginHelp": "Veuillez saisir votre identifiant", - "passwordLabel": "Mot de passe", - "passwordHelp": "Veuillez saisir votre mot de passe", - "remember": "Se souvenir de moi", - "forgotPassword": "Mot de passe oublié ?", - "loginButton": "Se connecter", - "loading": "Chargement…", - "noAccountYet": "Vous n’avez pas encore de compte ?", - "newAccount": "Créer un compte" - }, - - "pexels": { - "photoCredit": "Photo de {{photographer}} sur Pexels", - "videoCredit": "Vidéo de {{name}} sur Pexels", - "videoUnsupported": "Votre navigateur ne prend pas en charge la balise vidéo." - }, - - "footer": { - "copyright": "© {{year}} {{title}}. Tous droits réservés", - "privacy": "Politique de confidentialité" + "loginLabel": "Identifiant", + "loginHelp": "Veuillez entrer votre identifiant", + "passwordLabel": "Mot de passe", + "passwordHelp": "Veuillez entrer votre mot de passe", + "remember": "Se souvenir de moi", + "forgotPassword": "Mot de passe oublié?", + "loginButton": "Se connecter", + "loading": "Chargement...", + "noAccountYet": "Pas encore de compte?", + "newAccount": "Créer un compte" } - } - }, - "components": { - "widgetCreator": { - "title": "Créer un graphique ou un widget", - "helpText": "Décrivez votre nouveau widget ou graphique en langage naturel. Par exemple : \"Nombre d'utilisateurs administrateurs\" OU \"graphique rouge avec le nombre de contrats clôturés regroupés par mois\"", - "settingsTitle": "Paramètres du créateur de widget", - "settingsDescription": "Pour quel rôle affichons-nous et créons-nous des widgets ?", - "doneButton": "Terminé", - "loading": "Chargement..." }, - "search": { - "placeholder": "Rechercher", - "required": "Champ requis", - "minLength": "Longueur minimale : {{count}} caractères" + "exchange": { + "pageTitle": "Trading Spot", + "spot": "Spot", + "perpetual": "Perpétuel", + "seconds": "Contrat de secondes", + "buy": "Acheter", + "sell": "Vendre" } } -} +} \ No newline at end of file diff --git a/frontend/public/locales/ja/common.json b/frontend/public/locales/ja/common.json new file mode 100644 index 0000000..8a47061 --- /dev/null +++ b/frontend/public/locales/ja/common.json @@ -0,0 +1,46 @@ +{ + "nav": { + "markets": "マーケット", + "spot": "現物取引", + "perpetual": "先物取引", + "options": "オプション" + }, + "landing": { + "hero": { + "title": "ADML 取引所 | 世界をリードする暗号資産取引所", + "badge": "世界中で2000万人以上のユーザーに信頼されています", + "cta": "今すぐ開始" + } + }, + "exchange": { + "title": "現物取引", + "header": { + "spot": "現物", + "deposit": "入金" + }, + "panel": { + "buy": "買い", + "sell": "売り" + } + }, + "perpetual": { + "title": "先物取引", + "panel": { + "long": "ロング", + "short": "ショート" + } + }, + "seconds": { + "title": "バイナリーオプション", + "panel": { + "call": "コール (上昇)", + "put": "プット (下落)" + } + }, + "login": { + "title": "ログイン" + }, + "register": { + "title": "新規登録" + } +} diff --git a/frontend/public/locales/ko/common.json b/frontend/public/locales/ko/common.json new file mode 100644 index 0000000..269057c --- /dev/null +++ b/frontend/public/locales/ko/common.json @@ -0,0 +1,46 @@ +{ + "nav": { + "markets": "마켓", + "spot": "현물 거래", + "perpetual": "선물 거래", + "options": "옵션" + }, + "landing": { + "hero": { + "title": "ADML 거래소 | 세계 최고의 암호화폐 거래소", + "badge": "전 세계 2000만 명 이상의 사용자가 신뢰함", + "cta": "시작하기" + } + }, + "exchange": { + "title": "현물 거래", + "header": { + "spot": "현물", + "deposit": "입금" + }, + "panel": { + "buy": "매수", + "sell": "매도" + } + }, + "perpetual": { + "title": "선물 거래", + "panel": { + "long": "롱 오픈", + "short": "숏 오픈" + } + }, + "seconds": { + "title": "바이너리 옵션", + "panel": { + "call": "콜 (상승)", + "put": "풋 (하락)" + } + }, + "login": { + "title": "로그인" + }, + "register": { + "title": "회원가입" + } +} diff --git a/frontend/public/locales/ru/common.json b/frontend/public/locales/ru/common.json new file mode 100644 index 0000000..b561938 --- /dev/null +++ b/frontend/public/locales/ru/common.json @@ -0,0 +1,48 @@ +{ + "pages": { + "dashboard": { + "pageTitle": "Панель управления", + "overview": "Обзор биржи ADML", + "loadingWidgets": "Загрузка виджетов...", + "loading": "Загрузка..." + }, + "login": { + "pageTitle": "Вход", + "form": { + "loginLabel": "Логин", + "loginHelp": "Введите ваш логин", + "passwordLabel": "Пароль", + "passwordHelp": "Введите ваш пароль", + "remember": "Запомнить меня", + "forgotPassword": "Забыли пароль?", + "loginButton": "Войти", + "loading": "Загрузка...", + "noAccountYet": "Нет аккаунта?", + "newAccount": "Регистрация" + } + }, + "exchange": { + "pageTitle": "Спотовая торговля", + "spot": "Спот", + "perpetual": "Фьючерсы", + "seconds": "Опционы", + "buy": "Купить", + "sell": "Продать" + }, + "perpetual": { + "pageTitle": "Бессрочные контракты", + "leverage": "Плечо", + "cross": "Кросс", + "isolated": "Изолир.", + "long": "Лонг", + "short": "Шорт" + }, + "seconds": { + "pageTitle": "Опционы (Seconds)", + "duration": "Длительность", + "profit": "Доходность", + "call": "Вверх", + "put": "Вниз" + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/zh/common.json b/frontend/public/locales/zh/common.json new file mode 100644 index 0000000..e9c0b6b --- /dev/null +++ b/frontend/public/locales/zh/common.json @@ -0,0 +1,174 @@ +{ + "nav": { + "markets": "行情", + "spot": "现货交易", + "perpetual": "合约交易", + "options": "秒合约" + }, + "landing": { + "hero": { + "title": "ADML 交易所 | 全球领先的加密货币交易平台", + "badge": "全球 2000 万用户的信赖之选", + "title_part1": "交易未来", + "title_highlight": "就在 ADML", + "subtitle": "安全地购买、出售和交易 400 多种加密货币,享受低手续费和机构级安全保障。", + "input_placeholder": "邮箱 / 手机号码", + "cta": "立即开始" + }, + "stats": { + "24h_vol": "24小时成交量", + "users": "活跃用户", + "assets": "上架资产", + "uptime": "系统运行时间" + }, + "features": { + "security": { + "title": "安全第一", + "desc": "冷存储、多重签名钱包和 2FA 双重验证,保障所有资产安全。您的安全是我们的重中之重。" + }, + "speed": { + "title": "秒级执行", + "desc": "高性能撮合引擎,每秒处理超过 100 万笔交易,延迟低至亚毫秒级。" + }, + "support": { + "title": "24/7 客户支持", + "desc": "全球客服团队,支持 12 种语言,全天候为您解决任何问题。" + } + }, + "markets": { + "title": "行情趋势", + "tab": { + "popular": "热门", + "new": "新币", + "gainers": "涨幅榜" + }, + "view_all": "查看所有行情", + "col": { + "asset": "资产", + "price": "最新价", + "change": "24小时涨跌", + "volume": "成交量", + "action": "操作" + }, + "trade_btn": "去交易" + }, + "app": { + "title": "随时随地,随心交易", + "desc": "使用我们的专业移动应用程序,随时关注市场。支持 iOS、Android 和 Web。" + }, + "cta": { + "title": "立即开启您的交易之旅", + "desc": "加入全球最可靠的加密货币交易所。", + "btn_signup": "创建账户", + "btn_login": "演示登录" + } + }, + "exchange": { + "title": "现货交易", + "header": { + "spot": "现货", + "last_price": "最新价", + "change": "24h 涨跌", + "high": "24h 最高", + "low": "24h 最低", + "volume": "24h 成交量", + "deposit": "充值" + }, + "tabs": { + "open_orders": "当前委托", + "order_history": "历史委托", + "trade_history": "成交历史", + "assets": "资产" + }, + "orderbook": { + "title": "订单簿", + "price": "价格", + "amount": "数量" + }, + "panel": { + "buy": "买入", + "sell": "卖出", + "type": "订单类型", + "market": "市价", + "price": "价格", + "amount": "数量", + "available": "可用" + }, + "no_records": "暂无记录" + }, + "perpetual": { + "title": "合约交易", + "header": { + "perp": "永续", + "mark_price": "标记价格", + "funding": "资金费率 / 倒计时", + "change": "24h 涨跌", + "margin": "保证金", + "cross": "全仓", + "deposit": "充值" + }, + "tabs": { + "positions": "持有仓位", + "open_orders": "当前委托", + "order_history": "历史委托", + "trade_history": "成交历史" + }, + "panel": { + "long": "看涨/做多", + "short": "看跌/做空", + "mode": "仓位模式", + "cross": "全仓", + "price": "价格", + "amount": "数量", + "leverage": "调整杠杆", + "available": "可用平衡", + "max_long": "最大可开多", + "buy": "买入 / 做多", + "sell": "卖出 / 做空" + }, + "orderbook": { + "title": "深度图" + }, + "no_positions": "暂无持仓或委托" + }, + "seconds": { + "title": "秒合约", + "header": { + "contract": "期权合约", + "current_price": "当前价", + "yield": "预期收益", + "balance": "可用余额", + "deposit": "充值" + }, + "tabs": { + "current": "当前持仓", + "history": "交易历史" + }, + "panel": { + "period": "执行周期", + "yield": "收益率", + "amount": "投资金额", + "expected_profit": "预期利润", + "call": "看涨 (买升)", + "put": "看跌 (买降)", + "risk_warning": "风险提示:交易涉及显著的亏损风险,不适合所有投资者。" + }, + "no_history": "暂无活跃合约" + }, + "footer": { + "about": "专业、安全的数字资产交易平台。", + "section": { + "about": "关于我们", + "product": "产品中心", + "support": "服务支持", + "legal": "法律条款" + } + }, + "login": { + "title": "登录", + "demo_login": "演示账户登录" + }, + "register": { + "title": "注册" + } +} diff --git a/frontend/src/components/AsideMenuLayer.tsx b/frontend/src/components/AsideMenuLayer.tsx index eaa10bb..d945763 100644 --- a/frontend/src/components/AsideMenuLayer.tsx +++ b/frontend/src/components/AsideMenuLayer.tsx @@ -5,6 +5,7 @@ import AsideMenuList from './AsideMenuList' import { MenuAsideItem } from '../interfaces' import { useAppSelector } from '../stores/hooks' import Link from 'next/link'; +import Logo from './Logo'; type Props = { @@ -29,22 +30,19 @@ export default function AsideMenuLayer({ menu, className = '', ...props }: Props return ( ) -} +} \ No newline at end of file diff --git a/frontend/src/components/FooterBar.tsx b/frontend/src/components/FooterBar.tsx index 0acc9c5..16fe3aa 100644 --- a/frontend/src/components/FooterBar.tsx +++ b/frontend/src/components/FooterBar.tsx @@ -1,6 +1,5 @@ import React, { ReactNode } from 'react' import { containerMaxW } from '../config' -import Logo from './Logo' type Props = { children?: ReactNode @@ -10,26 +9,17 @@ export default function FooterBar({ children }: Props) { const year = new Date().getFullYear() return ( -
+ + + ); +}; + +ExchangePage.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default ExchangePage; \ No newline at end of file diff --git a/frontend/src/pages/index.tsx b/frontend/src/pages/index.tsx index 6fcf72f..7a0d826 100644 --- a/frontend/src/pages/index.tsx +++ b/frontend/src/pages/index.tsx @@ -1,166 +1,387 @@ - import React, { useEffect, useState } from 'react'; import type { ReactElement } from 'react'; import Head from 'next/head'; import Link from 'next/link'; +import * as icon from '@mdi/js'; +import { useTranslation } from 'next-i18next'; import BaseButton from '../components/BaseButton'; -import CardBox from '../components/CardBox'; -import SectionFullScreen from '../components/SectionFullScreen'; +import BaseIcon from '../components/BaseIcon'; import LayoutGuest from '../layouts/Guest'; -import BaseDivider from '../components/BaseDivider'; -import BaseButtons from '../components/BaseButtons'; import { getPageTitle } from '../config'; -import { useAppSelector } from '../stores/hooks'; -import CardBoxComponentTitle from "../components/CardBoxComponentTitle"; -import { getPexelsImage, getPexelsVideo } from '../helpers/pexels'; +import LanguageSwitcher from '../components/LanguageSwitcher'; +import Logo from '../components/Logo'; +const INITIAL_MARKET_DATA = [ + { symbol: 'BTCUSDT', name: 'Bitcoin', label: 'BTC', icon: icon.mdiBitcoin, price: '0', change: '0%', color: 'text-gray-400' }, + { symbol: 'ETHUSDT', name: 'Ethereum', label: 'ETH', icon: icon.mdiEthereum, price: '0', change: '0%', color: 'text-gray-400' }, + { symbol: 'SOLUSDT', name: 'Solana', label: 'SOL', icon: icon.mdiAlphaSCircle, price: '0', change: '0%', color: 'text-gray-400' }, + { symbol: 'BNBUSDT', name: 'BNB', label: 'BNB', icon: icon.mdiAlphaBCircle, price: '0', change: '0%', color: 'text-gray-400' }, + { symbol: 'ADAUSDT', name: 'Cardano', label: 'ADA', icon: icon.mdiAlphaACircle, price: '0', change: '0%', color: 'text-gray-400' }, + { symbol: 'XRPUSDT', name: 'Ripple', label: 'XRP', icon: icon.mdiAlphaXCircle, price: '0', change: '0%', color: 'text-gray-400' }, +]; -export default function Starter() { - const [illustrationImage, setIllustrationImage] = useState({ - src: undefined, - photographer: undefined, - photographer_url: undefined, - }) - const [illustrationVideo, setIllustrationVideo] = useState({video_files: []}) - const [contentType, setContentType] = useState('video'); - const [contentPosition, setContentPosition] = useState('right'); - const textColor = useAppSelector((state) => state.style.linkColor); +export default function LandingPage() { + const { t } = useTranslation('common'); + const [marketData, setMarketData] = useState(INITIAL_MARKET_DATA); - const title = 'AI App Draft' - - // Fetch Pexels image/video - useEffect(() => { - async function fetchData() { - const image = await getPexelsImage(); - const video = await getPexelsVideo(); - setIllustrationImage(image); - setIllustrationVideo(video); - } - fetchData(); - }, []); - - const imageBlock = (image) => ( -
-
- - Photo by {image?.photographer} on Pexels - -
-
- ); - - const videoBlock = (video) => { - if (video?.video_files?.length > 0) { - return ( -
- -
- - Video by {video.user.name} on Pexels - -
-
) - } + useEffect(() => { + const fetchMarketData = async () => { + try { + const symbols = INITIAL_MARKET_DATA.map(d => d.symbol); + const response = await fetch(`https://api.binance.com/api/v3/ticker/24hr?symbols=${JSON.stringify(symbols)}`); + const data = await response.json(); + + setMarketData(prev => prev.map(item => { + const ticker = data.find((t: any) => t.symbol === item.symbol); + if (ticker) { + const price = parseFloat(ticker.lastPrice).toLocaleString(undefined, { minimumFractionDigits: 2 }); + const change = parseFloat(ticker.priceChangePercent).toFixed(2); + return { + ...item, + price: price, + change: (parseFloat(change) >= 0 ? '+' : '') + change + '%', + color: parseFloat(change) >= 0 ? 'text-emerald-500' : 'text-rose-500', + }; + } + return item; + })); + } catch (error) { + console.error('Failed to fetch market data:', error); + } }; + fetchMarketData(); + const interval = setInterval(fetchMarketData, 5000); + return () => clearInterval(interval); + }, []); + return ( -
+
- {getPageTitle('Starter Page')} + {getPageTitle(t('landing.hero.title', { defaultValue: 'ADML Exchange | The World’s Leading Crypto Exchange' }))} - -
- {contentType === 'image' && contentPosition !== 'background' - ? imageBlock(illustrationImage) - : null} - {contentType === 'video' && contentPosition !== 'background' - ? videoBlock(illustrationVideo) - : null} -
- - - -
-

This is a React.js/Node.js app generated by the Flatlogic Web App Generator

-

For guides and documentation please check - your local README.md and the Flatlogic documentation

-
- - - - - -
+ {/* Navbar */} +
- -
-

© 2026 {title}. All rights reserved

- - Privacy Policy - -
+
+ + {t('login.title', { defaultValue: 'Log in' })} + +
+ + {/* Hero Section */} +
+
+
+ + {t('landing.hero.badge', { defaultValue: 'Trusted by 20M+ Users Globally' })} +
+

+ {t('landing.hero.title_part1', { defaultValue: 'Trade The Future' })}
+ + {t('landing.hero.title_highlight', { defaultValue: 'With ADML' })} + +

+

+ {t('landing.hero.subtitle', { defaultValue: 'Securely buy, sell and trade over 400+ cryptocurrencies with low fees and institutional-grade security.' })} +

+
+ + +
+ + {/* Quick Stats */} +
+ {[ + { label: '24h Vol', value: '$12.4B' }, + { label: 'Users', value: '25M+' }, + { label: 'Assets', value: '450+' }, + { label: 'Uptime', value: '99.99%' }, + ].map((stat, i) => ( +
+
{stat.value}
+
{t(`landing.stats.${stat.label.toLowerCase().replace(' ', '_')}`, { defaultValue: stat.label })}
+
+ ))} +
+
+ + {/* Background Decorative Elements */} +
+
+
+
+
+ + {/* Feature Sections (admlplus style) */} +
+
+
+
+
+ +
+

{t('landing.features.security.title', { defaultValue: 'Security First' })}

+

+ {t('landing.features.security.desc', { defaultValue: 'Cold storage, multi-sig wallets, and 2FA protection for all assets. Your security is our priority.' })} +

+
+
+
+ +
+

{t('landing.features.speed.title', { defaultValue: 'Instant Execution' })}

+

+ {t('landing.features.speed.desc', { defaultValue: 'Our high-performance matching engine handles 1M+ transactions per second with sub-millisecond latency.' })} +

+
+
+
+ +
+

{t('landing.features.support.title', { defaultValue: '24/7 Support' })}

+

+ {t('landing.features.support.desc', { defaultValue: 'Global customer support available in 12 languages around the clock to assist you with any issues.' })} +

+
+
+
+
+ + {/* Market Table */} +
+
+
+
+

{t('landing.markets.title', { defaultValue: 'Market Trends' })}

+
+ + + +
+
+ + {t('landing.markets.view_all', { defaultValue: 'View All Markets' })} → + +
+ +
+
+ + + + + + + + + + + + {marketData.map((coin) => ( + + + + + + + + ))} + +
{t('landing.markets.col.asset', { defaultValue: 'Asset' })}{t('landing.markets.col.price', { defaultValue: 'Price' })}{t('landing.markets.col.change', { defaultValue: '24h Change' })}{t('landing.markets.col.volume', { defaultValue: 'Volume' })}{t('landing.markets.col.action', { defaultValue: 'Action' })}
+
+
+ +
+
+
{coin.label}
+
{coin.name}
+
+
+
${coin.price}{coin.change} +
$2.4B
+
+ +
+
+
+
+
+ + {/* App Download Section (admlplus style) */} +
+
+
+
+

+ {t('landing.app.title', { defaultValue: 'Trade Anywhere, Anytime.' })} +

+

+ {t('landing.app.desc', { defaultValue: 'Stay connected to the markets with our professional mobile app. Available on iOS, Android, and Web.' })} +

+
+
+ +
+
Download on
+
App Store
+
+
+
+ +
+
Get it on
+
Google Play
+
+
+
+ +
+
+ {/* Mock QR Code */} +
+ +
+
+
+

{t('landing.app.qr_title', { defaultValue: 'Scan to download' })}

+

{t('landing.app.qr_desc', { defaultValue: 'Instant access to ADML features on your mobile device.' })}

+
+
+
+
+
+
+
+ +
+
+
Available Balance
+
$45,231.50
+
+
+
Deposit
+
Withdraw
+
+
+ {[1,2,3].map(i => ( +
+
+
+
+
+
+
+ ))} +
+
+
+
+
+
+
+
+
+ + {/* CTA Section */} +
+
+

{t('landing.cta.title', { defaultValue: 'Start Your Trade Now' })}

+

{t('landing.cta.desc', { defaultValue: 'Join the most reliable crypto exchange in the world.' })}

+
+ + +
+
+
+ + {/* Footer */} +
+
+
+
+ + + +

+ {t('footer.about', { defaultValue: 'Professional and secure digital asset trading platform.' })} +

+
+
+

{t('footer.section.about', { defaultValue: 'About' })}

+
    +
  • Company
  • +
  • Careers
  • +
  • News
  • +
+
+
+

{t('footer.section.product', { defaultValue: 'Product' })}

+
    +
  • Spot
  • +
  • Perpetual
  • +
  • Options
  • +
+
+
+

{t('footer.section.support', { defaultValue: 'Support' })}

+
    +
  • Help Center
  • +
  • API
  • +
  • Fees
  • +
+
+
+

{t('footer.section.legal', { defaultValue: 'Legal' })}

+
    +
  • Privacy
  • +
  • Terms
  • +
+
+
+
+

+ © 2026 ADML EXCHANGE. ALL RIGHTS RESERVED. +

+
+ + + +
+
+
+
+ +
); } -Starter.getLayout = function getLayout(page: ReactElement) { +LandingPage.getLayout = function getLayout(page: ReactElement) { return {page}; -}; - +}; \ No newline at end of file diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx index 0036268..578bc90 100644 --- a/frontend/src/pages/login.tsx +++ b/frontend/src/pages/login.tsx @@ -1,12 +1,10 @@ - - import React, { useEffect, useState } from 'react'; import type { ReactElement } from 'react'; import Head from 'next/head'; import BaseButton from '../components/BaseButton'; import CardBox from '../components/CardBox'; import BaseIcon from "../components/BaseIcon"; -import { mdiInformation, mdiEye, mdiEyeOff } from '@mdi/js'; +import { mdiInformation, mdiEye, mdiEyeOff, mdiAccountCircle } from '@mdi/js'; import SectionFullScreen from '../components/SectionFullScreen'; import LayoutGuest from '../layouts/Guest'; import { Field, Form, Formik } from 'formik'; @@ -21,6 +19,7 @@ import { useAppDispatch, useAppSelector } from '../stores/hooks'; import Link from 'next/link'; import {toast, ToastContainer} from "react-toastify"; import { getPexelsImage, getPexelsVideo } from '../helpers/pexels' +import Logo from '../components/Logo'; export default function Login() { const router = useRouter(); @@ -44,7 +43,7 @@ export default function Login() { password: '4b8a182c', remember: true }) - const title = 'AI App Draft' + const title = 'ADML EXCHANGE' // Fetch Pexels image/video useEffect( () => { @@ -92,6 +91,15 @@ export default function Login() { await dispatch(loginUser(rest)); }; + const handleDemoLogin = async () => { + const demoValues = { + email: 'admin@flatlogic.com', + password: '4b8a182c' + }; + setInitialValues({ ...demoValues, remember: true }); + await dispatch(loginUser(demoValues)); + }; + const setLogin = (target: HTMLElement) => { setInitialValues(prev => ({ ...prev, @@ -158,61 +166,35 @@ export default function Login() { -
+
{contentType === 'image' && contentPosition !== 'background' ? imageBlock(illustrationImage) : null} {contentType === 'video' && contentPosition !== 'background' ? videoBlock(illustrationVideo) : null}
- - -

{title}

- -
-
- -

Use{' '} - setLogin(e.target)}>admin@flatlogic.com{' / '} - 4b8a182c{' / '} - to login as Admin

-

Use setLogin(e.target)}>client@hello.com{' / '} - ed8b688f77aa{' / '} - to login as User

-
-
- -
+ +
+ +

Welcome to ADML

+

Please sign in to continue trading

-
- - + handleSubmit(values)} > -
+ - + label='Email / Account' + help='Enter your registered email'> +
- + help='Enter your password'> +
-
- +
+ - + Forgot password?
- + + -
-

+ +

Don’t have an account yet?{' '} - - New Account + + Create Account

+ +
+ Warning: Please verify the URL is adml-exchange.com to prevent phishing. +
-
-

© 2026 {title}. © All rights reserved

- - Privacy Policy - +
+

© 2026 ADML EXCHANGE. ALL RIGHTS RESERVED.

+
+ Privacy Policy + Terms of Service +
@@ -273,4 +269,4 @@ export default function Login() { Login.getLayout = function getLayout(page: ReactElement) { return {page}; -}; +}; \ No newline at end of file diff --git a/frontend/src/pages/markets.tsx b/frontend/src/pages/markets.tsx new file mode 100644 index 0000000..37634c0 --- /dev/null +++ b/frontend/src/pages/markets.tsx @@ -0,0 +1,160 @@ + +import React, { useEffect, useState } from 'react'; +import type { ReactElement } from 'react'; +import Head from 'next/head'; +import * as icon from '@mdi/js'; +import LayoutGuest from '../layouts/Guest'; +import SectionMain from '../components/SectionMain'; +import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton'; +import BaseIcon from '../components/BaseIcon'; +import BaseButton from '../components/BaseButton'; +import { getPageTitle } from '../config'; + +const INITIAL_MARKET_DATA = [ + { symbol: 'BTCUSDT', name: 'Bitcoin', label: 'BTC', icon: icon.mdiBitcoin }, + { symbol: 'ETHUSDT', name: 'Ethereum', label: 'ETH', icon: icon.mdiEthereum }, + { symbol: 'SOLUSDT', name: 'Solana', label: 'SOL', icon: icon.mdiAlphaSCircle }, + { symbol: 'BNBUSDT', name: 'BNB', label: 'BNB', icon: icon.mdiAlphaBCircle }, + { symbol: 'ADAUSDT', name: 'Cardano', label: 'ADA', icon: icon.mdiAlphaACircle }, + { symbol: 'XRPUSDT', name: 'Ripple', label: 'XRP', icon: icon.mdiAlphaXCircle }, + { symbol: 'DOTUSDT', name: 'Polkadot', label: 'DOT', icon: icon.mdiAlphaPCircle }, + { symbol: 'DOGEUSDT', name: 'Dogecoin', label: 'DOGE', icon: icon.mdiDog }, + { symbol: 'MATICUSDT', name: 'Polygon', label: 'MATIC', icon: icon.mdiHexagonMultiple }, + { symbol: 'LINKUSDT', name: 'Chainlink', label: 'LINK', icon: icon.mdiLinkVariant }, +]; + +const MarketsPage = () => { + const [marketData, setMarketData] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchMarketData = async () => { + try { + const symbols = INITIAL_MARKET_DATA.map(d => d.symbol); + const response = await fetch(`https://api.binance.com/api/v3/ticker/24hr?symbols=${JSON.stringify(symbols)}`); + const data = await response.json(); + + const mergedData = INITIAL_MARKET_DATA.map(item => { + const ticker = data.find((t: any) => t.symbol === item.symbol); + if (ticker) { + const price = parseFloat(ticker.lastPrice).toLocaleString(undefined, { minimumFractionDigits: 2 }); + const change = parseFloat(ticker.priceChangePercent).toFixed(2); + return { + ...item, + price: price, + change: (parseFloat(change) >= 0 ? '+' : '') + change + '%', + isPositive: parseFloat(change) >= 0, + volume: (parseFloat(ticker.quoteVolume) / 1000000).toFixed(2) + 'M', + high: parseFloat(ticker.highPrice).toLocaleString(), + low: parseFloat(ticker.lowPrice).toLocaleString(), + }; + } + return { ...item, price: '0', change: '0%', isPositive: true, volume: '0', high: '0', low: '0' }; + }); + setMarketData(mergedData); + setLoading(false); + } catch (error) { + console.error('Failed to fetch market data:', error); + } + }; + + fetchMarketData(); + const interval = setInterval(fetchMarketData, 5000); + return () => clearInterval(interval); + }, []); + + return ( + <> + + {getPageTitle('Markets')} + + + +
+ + + +
+
+ +
+ {marketData.slice(0, 3).map((coin) => ( +
+
+
+ + {coin.label}/USDT +
+ {coin.change} +
+
${coin.price}
+
24h Volume: {coin.volume}
+
+ ))} +
+ +
+
+ + + + + + + + + + + + + {marketData.map((asset) => ( + + + + + + + + + ))} + +
AssetPrice24h Change24h High/Low24h VolumeTrade
+
+ +
+
{asset.label}
+
{asset.name}
+
+
+
+
${asset.price}
+
+
+ {asset.change} +
+
+
H: {asset.high}
+
L: {asset.low}
+
+
{asset.volume} USDT
+
+ +
+
+
+
+ + ); +}; + +MarketsPage.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default MarketsPage; diff --git a/frontend/src/pages/perpetual.tsx b/frontend/src/pages/perpetual.tsx new file mode 100644 index 0000000..2345c73 --- /dev/null +++ b/frontend/src/pages/perpetual.tsx @@ -0,0 +1,228 @@ +import React, { ReactElement, useEffect, useState } from 'react'; +import Head from 'next/head'; +import * as icon from '@mdi/js'; +import { useTranslation } from 'react-i18next'; +import LayoutAuthenticated from '../layouts/Authenticated'; +import BaseIcon from '../components/BaseIcon'; +import BaseButton from '../components/BaseButton'; +import { getPageTitle } from '../config'; + +const PerpetualPage = () => { + const { t } = useTranslation('common'); + const [leverage, setLeverage] = useState(20); + const [side, setSide] = useState('long'); + const [currentTab, setCurrentTab] = useState('Positions'); + + useEffect(() => { + const script = document.createElement('script'); + script.src = 'https://s3.tradingview.com/tv.js'; + script.async = true; + script.onload = () => { + if (typeof window !== 'undefined' && (window as any).TradingView) { + new (window as any).TradingView.widget({ + "autosize": true, + "symbol": "BINANCE:BTCUSDT.P", + "interval": "D", + "timezone": "Etc/UTC", + "theme": "dark", + "style": "1", + "locale": "en", + "toolbar_bg": "#f1f3f6", + "enable_publishing": false, + "hide_side_toolbar": false, + "allow_symbol_change": true, + "container_id": "tradingview_chart" + }); + } + }; + document.head.appendChild(script); + }, []); + + return ( + <> + + {getPageTitle(t('perpetual.title', { defaultValue: 'Perpetual Trading' }))} + +
+ {/* Trading Header */} +
+
+
+
+ +
+
+
BTC/USDT
+
+ {t('perpetual.header.perp', { defaultValue: 'Perp' })} + {leverage}x +
+
+
+ +
+
+
{t('perpetual.header.mark_price', { defaultValue: 'Mark Price' })}
+
43,123.45
+
+
+
{t('perpetual.header.funding', { defaultValue: 'Funding / Countdown' })}
+
0.0100% / 04:21:05
+
+
+
{t('perpetual.header.change', { defaultValue: '24h Change' })}
+
+2.45%
+
+
+
+
+
+ {t('perpetual.header.margin', { defaultValue: 'Margin' })} + {t('perpetual.header.cross', { defaultValue: 'Cross' })} +
+ +
+
+ +
+ {/* Main Chart Area */} +
+
+ + {/* Positions/Orders Tabs */} +
+
+ {[ + t('perpetual.tabs.positions', { defaultValue: 'Positions' }), + t('perpetual.tabs.open_orders', { defaultValue: 'Open Orders' }), + t('perpetual.tabs.order_history', { defaultValue: 'Order History' }), + t('perpetual.tabs.trade_history', { defaultValue: 'Trade History' }) + ].map((tab) => ( + + ))} +
+
+ +

+ {t('perpetual.no_positions', { defaultValue: 'No active positions or orders' })} +

+
+
+
+ + {/* Trade Panel */} +
+ {/* Mode Selector */} +
+
+ + +
+ +
+
+ {t('perpetual.panel.mode', { defaultValue: 'Margin Mode' })} + {t('perpetual.panel.cross', { defaultValue: 'Cross' })} {leverage}x +
+ +
+ {t('perpetual.panel.price', { defaultValue: 'Price' })} + + USDT +
+ +
+ {t('perpetual.panel.amount', { defaultValue: 'Amount' })} + + Cont +
+ + {/* Leverage Slider Mock */} +
+
+ {t('perpetual.panel.leverage', { defaultValue: 'Adjust Leverage' })} + {leverage}x +
+ setLeverage(parseInt(e.target.value))} + className="w-full h-1 bg-white/10 rounded-full appearance-none cursor-pointer accent-blue-500" + /> +
+ 1x + 25x + 50x + 75x + 100x + 125x +
+
+ +
+
+ {t('perpetual.panel.available', { defaultValue: 'Available' })} + 0.00 USDT +
+
+ {t('perpetual.panel.max_long', { defaultValue: 'Max Long' })} + 0.000 BTC +
+
+ + +
+
+ + {/* Order Book Minimal */} +
+

{t('perpetual.orderbook.title', { defaultValue: 'Market Depth' })}

+
+ {[...Array(6)].map((_, i) => ( +
+ 43,{(123 + (6-i)*5).toString().padStart(3, '0')}.45 + {(Math.random() * 5).toFixed(2)} +
+ ))} +
+ 43,123.45 +
+ {[...Array(6)].map((_, i) => ( +
+ 43,{(123 - i*5).toString().padStart(3, '0')}.45 + {(Math.random() * 5).toFixed(2)} +
+ ))} +
+
+
+
+
+ + ); +}; + +PerpetualPage.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default PerpetualPage; \ No newline at end of file diff --git a/frontend/src/pages/second-contract.tsx b/frontend/src/pages/second-contract.tsx new file mode 100644 index 0000000..9009a6c --- /dev/null +++ b/frontend/src/pages/second-contract.tsx @@ -0,0 +1,198 @@ +import React, { ReactElement, useEffect, useState } from 'react'; +import Head from 'next/head'; +import * as icon from '@mdi/js'; +import { useTranslation } from 'react-i18next'; +import LayoutAuthenticated from '../layouts/Authenticated'; +import BaseIcon from '../components/BaseIcon'; +import BaseButton from '../components/BaseButton'; +import { getPageTitle } from '../config'; + +const SecondContractPage = () => { + const { t } = useTranslation('common'); + const [amount, setAmount] = useState('100'); + const [period, setPeriod] = useState(60); + const [profit, setProfit] = useState(85); + + useEffect(() => { + const script = document.createElement('script'); + script.src = 'https://s3.tradingview.com/tv.js'; + script.async = true; + script.onload = () => { + if (typeof window !== 'undefined' && (window as any).TradingView) { + new (window as any).TradingView.widget({ + "autosize": true, + "symbol": "BINANCE:BTCUSDT", + "interval": "1", + "timezone": "Etc/UTC", + "theme": "dark", + "style": "1", + "locale": "en", + "toolbar_bg": "#f1f3f6", + "enable_publishing": false, + "hide_side_toolbar": false, + "allow_symbol_change": true, + "container_id": "tradingview_chart" + }); + } + }; + document.head.appendChild(script); + }, []); + + return ( + <> + + {getPageTitle(t('seconds.title', { defaultValue: 'Binary Options' }))} + +
+ {/* Header */} +
+
+
+
+ +
+
+
BTC/USDT
+
{t('seconds.header.contract', { defaultValue: 'Option Contract' })}
+
+
+ +
+
+
{t('seconds.header.current_price', { defaultValue: 'Current Price' })}
+
43,123.45
+
+
+
{t('seconds.header.yield', { defaultValue: 'Estimated Yield' })}
+
+{profit}%
+
+
+
+
+
+
{t('seconds.header.balance', { defaultValue: 'Available Balance' })}
+
0.00 USDT
+
+ +
+
+ +
+ {/* Chart Area */} +
+
+ + {/* Quick Stats Overlay */} +
+ {[ + { label: '30s', yield: '75%' }, + { label: '60s', yield: '85%' }, + { label: '120s', yield: '90%' }, + { label: '300s', yield: '95%' } + ].map((t) => ( +
+
{t.label}
+
{t.yield}
+
+ ))} +
+ + {/* History Tabs */} +
+
+ {[ + t('seconds.tabs.current', { defaultValue: 'Current Positions' }), + t('seconds.tabs.history', { defaultValue: 'Trade History' }) + ].map((tab, i) => ( + + ))} +
+
+ +

+ {t('seconds.no_history', { defaultValue: 'No active contracts' })} +

+
+
+
+ + {/* Trade Panel */} +
+
+ {/* Period Selection */} +
+

{t('seconds.panel.period', { defaultValue: 'Execution Period' })}

+
+ {[30, 60, 120, 300].map(s => ( + + ))} +
+
+ + {/* Amount Input */} +
+

{t('seconds.panel.amount', { defaultValue: 'Investment Amount' })}

+
+ USDT + setAmount(e.target.value)} + className="w-full bg-[#111111] border border-white/10 rounded-2xl pl-16 pr-4 py-4 text-xl font-black text-white focus:border-blue-500/50 outline-none transition-all" + /> +
+
+ {[100, 500, 1000, 5000].map(v => ( + + ))} +
+
+ + {/* Expected Profit */} +
+
+ {t('seconds.panel.expected_profit', { defaultValue: 'Expected Profit' })} + +{profit}% +
+
+ +${(parseFloat(amount || '0') * profit / 100).toFixed(2)} +
+
+ + {/* Trade Buttons */} +
+ + +
+ +

+ {t('seconds.panel.risk_warning', { defaultValue: 'Risk Warning: Trading involves significant risk of loss and is not suitable for all investors.' })} +

+
+
+
+
+ + ); +}; + +SecondContractPage.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default SecondContractPage; \ No newline at end of file diff --git a/frontend/src/styles.ts b/frontend/src/styles.ts index a969b60..2d1b7d1 100644 --- a/frontend/src/styles.ts +++ b/frontend/src/styles.ts @@ -25,34 +25,56 @@ interface StyleObject { } export const white: StyleObject = { - aside: 'bg-white dark:text-white', + aside: 'bg-white dark:text-white border-r border-gray-100', asideScrollbars: 'aside-scrollbars-light', - asideBrand: '', - asideMenuItem: 'text-gray-700 hover:bg-gray-100/70 dark:text-dark-500 dark:hover:text-white dark:hover:bg-dark-800', - asideMenuItemActive: 'font-bold text-black dark:text-white', - asideMenuDropdown: 'bg-gray-100/75', - navBarItemLabel: 'text-blue-600', - navBarItemLabelHover: 'hover:text-black', - navBarItemLabelActiveColor: 'text-black', + asideBrand: 'border-b border-gray-100', + asideMenuItem: 'text-gray-700 hover:bg-gray-50 dark:text-dark-500 dark:hover:text-white dark:hover:bg-dark-800', + asideMenuItemActive: 'font-bold text-blue-600 dark:text-white bg-blue-50/50', + asideMenuDropdown: 'bg-gray-50', + navBarItemLabel: 'text-gray-600', + navBarItemLabelHover: 'hover:text-blue-600', + navBarItemLabelActiveColor: 'text-blue-600', overlay: 'from-white via-gray-100 to-white', - activeLinkColor: 'bg-gray-100/70', + activeLinkColor: 'bg-gray-50', bgLayoutColor: 'bg-gray-50', - iconsColor: 'text-blue-500', + iconsColor: 'text-blue-600', cardsColor: 'bg-white', - focusRingColor: 'focus:ring focus:ring-blue-600 focus:border-blue-600 focus:outline-none border-gray-300 dark:focus:ring-blue-600 dark:focus:border-blue-600', - corners: 'rounded', - cardsStyle: 'bg-white border border-pavitra-400', + focusRingColor: 'focus:ring focus:ring-blue-600 focus:border-blue-600 focus:outline-none border-gray-200', + corners: 'rounded-2xl', + cardsStyle: 'bg-white border border-gray-100 shadow-sm', linkColor: 'text-blue-600', - websiteHeder: 'border-b border-gray-200', - borders: 'border-gray-200', - shadow: '', - websiteSectionStyle: '', - textSecondary: 'text-gray-500', + websiteHeder: 'border-b border-gray-100 bg-white/80 backdrop-blur-md', + borders: 'border-gray-100', + shadow: 'shadow-sm', + websiteSectionStyle: 'bg-gray-50', + textSecondary: 'text-gray-400', } - - - +export const basic: StyleObject = { + aside: 'bg-[#0a0a0a] border-r border-white/5', + asideScrollbars: 'aside-scrollbars-gray', + asideBrand: 'bg-[#0a0a0a] border-b border-white/5', + asideMenuItem: 'text-gray-400 hover:text-white hover:bg-white/5', + asideMenuItemActive: 'font-bold text-white bg-blue-600/10', + asideMenuDropdown: 'bg-white/5', + navBarItemLabel: 'text-gray-400', + navBarItemLabelHover: 'hover:text-white', + navBarItemLabelActiveColor: 'text-blue-500', + overlay: 'from-[#0a0a0a] via-[#111111] to-[#0a0a0a]', + activeLinkColor: 'bg-white/5', + bgLayoutColor: 'bg-[#000000]', + iconsColor: 'text-blue-500', + cardsColor: 'bg-[#0d0d0d]', + focusRingColor: 'focus:ring focus:ring-blue-600 focus:border-blue-600 focus:outline-none border-white/10', + corners: 'rounded-2xl', + cardsStyle: 'bg-[#0d0d0d] border border-white/5 shadow-2xl', + linkColor: 'text-blue-500', + websiteHeder: 'bg-black/80 backdrop-blur-md border-b border-white/5', + borders: 'border-white/5', + shadow: 'shadow-2xl', + websiteSectionStyle: 'bg-black', + textSecondary: 'text-gray-500', +} export const dataGridStyles = { '& .MuiDataGrid-cell': { @@ -78,30 +100,4 @@ export const dataGridStyles = { '& .MuiDataGrid-root': { border: 'none', }, -}; - -export const basic: StyleObject = { - aside: 'bg-gray-800', - asideScrollbars: 'aside-scrollbars-gray', - asideBrand: 'bg-gray-900 text-white', - asideMenuItem: 'text-gray-300 hover:text-white', - asideMenuItemActive: 'font-bold text-white', - asideMenuDropdown: 'bg-gray-700/50', - navBarItemLabel: 'text-black', - navBarItemLabelHover: 'hover:text-blue-500', - navBarItemLabelActiveColor: 'text-blue-600', - overlay: 'from-gray-700 via-gray-900 to-gray-700', - activeLinkColor: 'bg-gray-100/70', - bgLayoutColor: 'bg-gray-50', - iconsColor: 'text-blue-500', - cardsColor: 'bg-white', - focusRingColor: 'focus:ring focus:ring-blue-600 focus:border-blue-600 focus:outline-none dark:focus:ring-blue-600 border-gray-300 dark:focus:border-blue-600', - corners: 'rounded', - cardsStyle: 'bg-white border border-pavitra-400', - linkColor: 'text-black', - websiteHeder: '', - borders: '', - shadow: '', - websiteSectionStyle: '', - textSecondary: '', -} +}; \ No newline at end of file