Autosave: 20260125-141514

This commit is contained in:
Flatlogic Bot 2026-01-25 14:15:14 +00:00
parent 36e049bd4d
commit 7490a909b5
33 changed files with 2035 additions and 619 deletions

View File

@ -129,8 +129,8 @@
<p class="tip">The application is currently launching. The page will automatically refresh once site is
available.</p>
<div class="project-info">
<h2>AI App Draft</h2>
<p>Crypto trading platform inspired by OKX with exchange, wallets, orders, and KYC.</p>
<h2>ADML Exchange</h2>
<p>Professional crypto trading platform with spot, perpetual contracts, and second contracts.</p>
</div>
<div class="loader-container">
<img src="https://flatlogic.com/blog/wp-content/uploads/2025/05/logo-bot-1.png" alt="App Logo"
@ -184,4 +184,4 @@
</script>
</body>
</html>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -1,6 +1,3 @@
const os = require('os');
const config = {
@ -39,7 +36,7 @@ const config = {
},
uploadDir: os.tmpdir(),
email: {
from: 'AI App Draft <app@flatlogic.app>',
from: 'ADML Exchange <app@adml-exchange.com>',
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;

View File

@ -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

View File

@ -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"
}
}
}
}

View File

@ -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 Worlds 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": "Dont 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"
}
}

View File

@ -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"
}
}
}
}

View File

@ -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 quadministrateur",
"sampleCredentialsUser": "Utilisez {{email}} / {{password}} pour vous connecter en tant quutilisateur",
"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 navez 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"
}
}
}
}

View File

@ -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": "新規登録"
}
}

View File

@ -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": "회원가입"
}
}

View File

@ -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": "Вниз"
}
}
}

View File

@ -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": "注册"
}
}

View File

@ -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 (
<aside
id='asideMenu'
className={`${className} zzz lg:py-2 lg:pl-2 w-60 fixed flex z-40 top-0 h-screen transition-position overflow-hidden`}
className={`${className} zzz lg:py-2 lg:pl-2 w-64 fixed flex z-40 top-0 h-screen transition-position overflow-hidden`}
>
<div
className={`flex-1 flex flex-col overflow-hidden dark:bg-dark-900 ${asideStyle} ${corners}`}
className={`flex-1 flex flex-col overflow-hidden dark:bg-[#0a0a0a] ${asideStyle} ${corners}`}
>
<div
className={`flex flex-row h-14 items-center justify-between ${asideBrandStyle}`}
className={`flex flex-row h-16 items-center justify-between px-6 ${asideBrandStyle}`}
>
<div className="text-center flex-1 lg:text-left lg:pl-6 xl:text-center xl:pl-0">
<b className="font-black">AI App Draft</b>
</div>
<Link href="/dashboard" className="flex-1 flex items-center justify-center lg:justify-start">
<Logo className="scale-75 origin-left" />
</Link>
<button
className="hidden lg:inline-block xl:hidden p-3"
className="hidden lg:inline-block xl:hidden p-3 text-gray-500 hover:text-white"
onClick={handleAsideLgCloseClick}
>
<BaseIcon path={mdiClose} />
@ -60,4 +58,4 @@ export default function AsideMenuLayer({ menu, className = '', ...props }: Props
</div>
</aside>
)
}
}

View File

@ -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 (
<footer className={`py-2 px-6 ${containerMaxW}`}>
<div className="block md:flex items-center justify-between">
<div className="text-center md:text-left mb-6 md:mb-0">
<b>
&copy;{year},{` `}
<a href="https://flatlogic.com/" rel="noreferrer" target="_blank">
Flatlogic
</a>
.
</b>
{` `}
{children}
<footer className={`py-6 px-6 ${containerMaxW} border-t border-white/5`}>
<div className="flex flex-col md:flex-row items-center justify-between gap-4 text-center md:text-left">
<div className="text-[10px] font-black uppercase tracking-[0.2em] text-gray-500">
&copy; {year} ADML EXCHANGE. ALL RIGHTS RESERVED.
</div>
<div className="flex items-center space-x-6 text-[10px] font-black uppercase tracking-widest text-gray-600">
<a href="#" className="hover:text-blue-500 transition-colors">Privacy Policy</a>
<a href="#" className="hover:text-blue-500 transition-colors">Terms of Service</a>
<a href="#" className="hover:text-blue-500 transition-colors">Risk Warning</a>
</div>
<div className="flex item-center md:py-2 gap-4">
<a href="https://flatlogic.com/" rel="noreferrer" target="_blank">
<Logo className="w-auto h-8 md:h-6 mx-auto" />
</a>
</div>
</div>
</footer>
)
}
}

View File

@ -1,13 +1,18 @@
import React, { useEffect, useState } from 'react';
import Select, { components, SingleValueProps, OptionProps } from 'react-select';
import { useTranslation } from 'react-i18next';
type LanguageOption = { label: string; value: string };
const LANGS: LanguageOption[] = [
{ value: 'en', label: '🇬🇧 EN' },
{ value: 'zh', label: '🇨🇳 ZH' },
{ value: 'fr', label: '🇫🇷 FR' },
{ value: 'es', label: '🇪🇸 ES' },
{ value: 'de', label: '🇩🇪 DE' },
{ value: 'ja', label: '🇯🇵 JA' },
{ value: 'ko', label: '🇰🇷 KO' },
{ value: 'ru', label: '🇷🇺 RU' },
];
const Option = (props: OptionProps<LanguageOption, false>) => (
@ -23,22 +28,26 @@ const SingleVal = (props: SingleValueProps<LanguageOption, false>) => (
);
const LanguageSwitcher: React.FC = () => {
const { i18n } = useTranslation();
const [mounted, setMounted] = useState(false);
const [selected, setSelected] = useState<LanguageOption>(LANGS[0]);
useEffect(() => {
setMounted(true);
}, []);
const currentLang = LANGS.find(l => l.value === i18n.language) || LANGS[0];
setSelected(currentLang);
}, [i18n.language]);
const handleChange = (opt: LanguageOption | null) => {
if (!opt) return;
i18n.changeLanguage(opt.value);
setSelected(opt);
};
if (!mounted) return null;
return (
<div style={{ width: 88 }}>
<div style={{ width: 100 }}>
<Select
value={selected}
options={LANGS}
@ -53,12 +62,13 @@ const LanguageSwitcher: React.FC = () => {
styles={{
control: (base) => ({
...base,
minHeight: 28,
height: 28,
minHeight: 32,
height: 32,
paddingTop: 0,
paddingBottom: 0,
borderColor: '#d1d5db',
cursor: 'pointer',
backgroundColor: 'transparent',
}),
valueContainer: (base) => ({
...base,
@ -68,7 +78,7 @@ const LanguageSwitcher: React.FC = () => {
}),
indicatorsContainer: (base) => ({
...base,
height: 24,
height: 28,
}),
dropdownIndicator: (base) => ({
...base,
@ -78,7 +88,7 @@ const LanguageSwitcher: React.FC = () => {
...base,
paddingTop: 4,
paddingBottom: 4,
height: 26,
height: 32,
fontSize: '0.875rem',
backgroundColor: state.isFocused ? '#f3f4f6' : 'white',
color: '#111827',
@ -93,4 +103,4 @@ const LanguageSwitcher: React.FC = () => {
);
};
export default LanguageSwitcher;
export default LanguageSwitcher;

View File

@ -6,10 +6,18 @@ type Props = {
export default function Logo({ className = '' }: Props) {
return (
<img
src={"https://flatlogic.com/logo.svg"}
className={className}
alt={'Flatlogic logo'}>
</img>
<div className={`flex items-center space-x-2 ${className}`}>
<div className="relative w-10 h-10 group">
<div className="absolute inset-0 bg-blue-600 rounded-xl rotate-6 group-hover:rotate-0 transition-transform duration-300"></div>
<div className="absolute inset-0 bg-black border-2 border-blue-500 rounded-xl flex items-center justify-center font-black text-blue-500 text-xl overflow-hidden">
A
<div className="absolute -bottom-1 -right-1 w-4 h-4 bg-blue-500 rotate-45"></div>
</div>
</div>
<div className="flex flex-col leading-none">
<span className="font-black text-2xl tracking-tighter italic">ADML</span>
<span className="text-[8px] font-bold text-blue-500 tracking-[0.2em] uppercase ml-0.5">Exchange</span>
</div>
</div>
)
}

View File

@ -6,6 +6,7 @@ import NavBarItemPlain from './NavBarItemPlain'
import NavBarMenuList from './NavBarMenuList'
import { MenuNavBarItem } from '../interfaces'
import { useAppSelector } from '../stores/hooks';
import LanguageSwitcher from './LanguageSwitcher'
type Props = {
menu: MenuNavBarItem[]
@ -39,6 +40,9 @@ export default function NavBar({ menu, className = '', children }: Props) {
>
<div className={`flex lg:items-stretch ${containerMaxW} ${isScrolled && `border-b border-pavitra-400 dark:border-dark-700`}`}>
<div className="flex flex-1 items-stretch h-14">{children}</div>
<div className="flex items-center px-3 lg:hidden">
<LanguageSwitcher />
</div>
<div className="flex-none items-stretch flex h-14 lg:hidden">
<NavBarItemPlain onClick={handleMenuNavBarToggleClick}>
<BaseIcon path={isMenuNavBarActive ? mdiClose : mdiDotsVertical} size="24" />
@ -49,9 +53,12 @@ export default function NavBar({ menu, className = '', children }: Props) {
isMenuNavBarActive ? 'block' : 'hidden'
} flex items-center max-h-screen-menu overflow-y-auto lg:overflow-visible absolute w-screen top-14 left-0 ${bgColor} shadow-lg lg:w-auto lg:flex lg:static lg:shadow-none dark:bg-dark-800`}
>
<div className="hidden lg:flex items-center px-4">
<LanguageSwitcher />
</div>
<NavBarMenuList menu={menu} />
</div>
</div>
</nav>
)
}
}

View File

@ -1,6 +1,5 @@
import React, {useEffect, useRef} from 'react'
import React, { useEffect, useRef, useState } from 'react'
import Link from 'next/link'
import { useState } from 'react'
import { mdiChevronUp, mdiChevronDown } from '@mdi/js'
import BaseDivider from './BaseDivider'
import BaseIcon from './BaseIcon'
@ -129,4 +128,4 @@ export default function NavBarItem({ item }: Props) {
}
return <div className={componentClass} ref={excludedRef}>{NavBarItemComponentContents}</div>
}
}

View File

@ -1,15 +1,13 @@
export const hostApi = process.env.NODE_ENV === 'development' && !process.env.NEXT_PUBLIC_BACK_API ? 'http://localhost' : ''
export const portApi = process.env.NODE_ENV === 'development' && !process.env.NEXT_PUBLIC_BACK_API ? 8080 : '';
export const baseURLApi = `${hostApi}${portApi ? `:${portApi}` : ``}/api`
export const containerMaxW = 'container lg:mx-auto'
export const appTitle = 'ADML Exchange'
export const getPageTitle = (pageTitle: string) => `${pageTitle}${appTitle}`
export const baseURLApi = process.env.NEXT_PUBLIC_BACK_API || '/api'
export const tinyKey = process.env.NEXT_PUBLIC_TINY_KEY || ''
export const localStorageDarkModeKey = 'darkMode'
export const localStorageStyleKey = 'style'
export const containerMaxW = 'xl:max-w-full xl:mx-auto 2xl:mx-20'
export const appTitle = 'created by Flatlogic generator!'
export const getPageTitle = (currentPageTitle: string) => `${currentPageTitle}${appTitle}`
export const tinyKey = process.env.NEXT_PUBLIC_TINY_KEY || ''
export const localStorageStyleKey = 'style'

View File

@ -9,6 +9,8 @@ i18n
.use(initReactI18next)
.init({
fallbackLng: 'en',
ns: ['common'],
defaultNS: 'common',
detection: {
order: ['localStorage', 'navigator'],
lookupLocalStorage: 'app_lang_',
@ -18,4 +20,6 @@ i18n
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
interpolation: { escapeValue: false },
});
});
export default i18n;

View File

@ -1,7 +1,6 @@
import React, { ReactNode, useEffect } from 'react'
import { useState } from 'react'
import React, { ReactNode, useEffect, useState } from 'react'
import jwt from 'jsonwebtoken';
import { mdiForwardburger, mdiBackburger, mdiMenu } from '@mdi/js'
import { mdiForwardburger, mdiBackburger, mdiMenu, mdiAlertCircle } from '@mdi/js'
import menuAside from '../menuAside'
import menuNavBar from '../menuNavBar'
import BaseIcon from '../components/BaseIcon'
@ -13,6 +12,7 @@ import { useAppDispatch, useAppSelector } from '../stores/hooks'
import Search from '../components/Search';
import { useRouter } from 'next/router'
import {findMe, logoutUser} from "../stores/authSlice";
import { useTranslation } from 'react-i18next';
import {hasPermission} from "../helpers/userPermissions";
@ -32,6 +32,7 @@ export default function LayoutAuthenticated({
}: Props) {
const dispatch = useAppDispatch()
const router = useRouter()
const { t } = useTranslation('common');
const { token, currentUser } = useAppSelector((state) => state.auth)
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
let localToken
@ -86,18 +87,19 @@ export default function LayoutAuthenticated({
}, [router.events, dispatch])
const layoutAsidePadding = 'xl:pl-60'
const layoutAsidePadding = 'xl:pl-64'
const isDemo = currentUser?.email === 'admin@flatlogic.com'
return (
<div className={`${darkMode ? 'dark' : ''} overflow-hidden lg:overflow-visible`}>
<div
className={`${layoutAsidePadding} ${
isAsideMobileExpanded ? 'ml-60 lg:ml-0' : ''
} pt-14 min-h-screen w-screen transition-position lg:w-auto ${bgColor} dark:bg-dark-800 dark:text-slate-100`}
isAsideMobileExpanded ? 'ml-64 lg:ml-0' : ''
} pt-14 min-h-screen w-screen transition-position lg:w-auto ${bgColor} dark:bg-[#000000] dark:text-slate-100`}
>
<NavBar
menu={menuNavBar}
className={`${layoutAsidePadding} ${isAsideMobileExpanded ? 'ml-60 lg:ml-0' : ''}`}
className={`${layoutAsidePadding} ${isAsideMobileExpanded ? 'ml-64 lg:ml-0' : ''}`}
>
<NavBarItemPlain
display="flex lg:hidden"
@ -111,6 +113,12 @@ export default function LayoutAuthenticated({
>
<BaseIcon path={mdiMenu} size="24" />
</NavBarItemPlain>
{isDemo && (
<div className="hidden md:flex items-center px-4 py-1.5 bg-blue-600/10 border border-blue-500/20 rounded-full text-blue-500 text-[10px] font-black uppercase tracking-widest ml-4">
<BaseIcon path={mdiAlertCircle} size={14} className="mr-2" />
{t('demo.badge', { defaultValue: 'Demo Mode' })}
</div>
)}
<NavBarItemPlain useMargin>
<Search />
</NavBarItemPlain>
@ -121,8 +129,12 @@ export default function LayoutAuthenticated({
menu={menuAside}
onAsideLgClose={() => setIsAsideLgActive(false)}
/>
{children}
<FooterBar>Hand-crafted & Made with </FooterBar>
<div className="flex-1">
{children}
</div>
<FooterBar>
<span className="text-[10px] font-black uppercase tracking-widest opacity-40">&copy; 2026 ADML Exchange. Global Reliable Trading.</span>
</FooterBar>
</div>
</div>
)

View File

@ -7,11 +7,10 @@ type Props = {
export default function LayoutGuest({ children }: Props) {
const darkMode = useAppSelector((state) => state.style.darkMode)
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
return (
<div className={darkMode ? 'dark' : ''}>
<div className={`${bgColor} dark:bg-slate-800 dark:text-slate-100`}>{children}</div>
<div className={`bg-[#000000] text-white dark:bg-[#000000] dark:text-slate-100 min-h-screen`}>{children}</div>
</div>
)
}
}

View File

@ -5,127 +5,129 @@ const menuAside: MenuAsideItem[] = [
{
href: '/dashboard',
icon: icon.mdiViewDashboardOutline,
label: 'Dashboard',
},
{
href: '/users/users-list',
label: 'Users',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: icon.mdiAccountGroup ?? icon.mdiTable,
permissions: 'READ_USERS'
label: 'Overview',
},
{
href: '/roles/roles-list',
label: 'Roles',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: icon.mdiShieldAccountVariantOutline ?? icon.mdiTable,
permissions: 'READ_ROLES'
label: 'Trading',
icon: icon.mdiSwapHorizontal,
menu: [
{
href: '/markets',
label: 'Markets',
icon: icon.mdiGlobeLight,
},
{
href: '/exchange',
label: 'Spot Trading',
icon: icon.mdiChartLine,
},
{
href: '/perpetual',
label: 'Perpetual Trading',
icon: icon.mdiChartTimelineVariant,
},
{
href: '/second-contract',
label: 'Seconds Trading',
icon: icon.mdiFlash,
},
{
href: '/orders/orders-list',
label: 'Orders',
icon: icon.mdiClipboardListOutline,
permissions: 'READ_ORDERS'
},
{
href: '/trades/trades-list',
label: 'Trade History',
icon: icon.mdiHistory,
permissions: 'READ_TRADES'
},
]
},
{
href: '/permissions/permissions-list',
label: 'Permissions',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: icon.mdiShieldAccountOutline ?? icon.mdiTable,
permissions: 'READ_PERMISSIONS'
label: 'Wallet',
icon: icon.mdiWallet,
menu: [
{
href: '/assets/assets-list',
label: 'Assets',
icon: icon.mdiCurrencyUsd,
permissions: 'READ_ASSETS'
},
{
href: '/wallets/wallets-list',
label: 'My Wallets',
icon: icon.mdiWallet,
permissions: 'READ_WALLETS'
},
{
href: '/deposits/deposits-list',
label: 'Deposits',
icon: icon.mdiBankTransferIn,
permissions: 'READ_DEPOSITS'
},
{
href: '/withdrawals/withdrawals-list',
label: 'Withdrawals',
icon: icon.mdiBankTransferOut,
permissions: 'READ_WITHDRAWALS'
},
{
href: '/transactions/transactions-list',
label: 'Transactions',
icon: icon.mdiReceipt,
permissions: 'READ_TRANSACTIONS'
},
]
},
{
href: '/assets/assets-list',
label: 'Assets',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiCurrencyUsd' in icon ? icon['mdiCurrencyUsd' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_ASSETS'
label: 'Verification',
icon: icon.mdiShieldCheckOutline,
menu: [
{
href: '/kyc_documents/kyc_documents-list',
label: 'KYC Documents',
icon: icon.mdiFileDocument,
permissions: 'READ_KYC_DOCUMENTS'
},
{
href: '/support_tickets/support_tickets-list',
label: 'Support Tickets',
icon: icon.mdiHeadset,
permissions: 'READ_SUPPORT_TICKETS'
},
]
},
{
href: '/trading_pairs/trading_pairs-list',
label: 'Trading pairs',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiSwapHorizontal' in icon ? icon['mdiSwapHorizontal' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_TRADING_PAIRS'
},
{
href: '/wallets/wallets-list',
label: 'Wallets',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiWallet' in icon ? icon['mdiWallet' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_WALLETS'
},
{
href: '/orders/orders-list',
label: 'Orders',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiChartLine' in icon ? icon['mdiChartLine' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_ORDERS'
},
{
href: '/trades/trades-list',
label: 'Trades',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiSwapVertical' in icon ? icon['mdiSwapVertical' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_TRADES'
},
{
href: '/deposits/deposits-list',
label: 'Deposits',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiBankTransferIn' in icon ? icon['mdiBankTransferIn' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_DEPOSITS'
},
{
href: '/withdrawals/withdrawals-list',
label: 'Withdrawals',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiBankTransferOut' in icon ? icon['mdiBankTransferOut' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_WITHDRAWALS'
},
{
href: '/kyc_documents/kyc_documents-list',
label: 'Kyc documents',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiFileDocument' in icon ? icon['mdiFileDocument' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_KYC_DOCUMENTS'
},
{
href: '/transactions/transactions-list',
label: 'Transactions',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiReceipt' in icon ? icon['mdiReceipt' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_TRANSACTIONS'
},
{
href: '/support_tickets/support_tickets-list',
label: 'Support tickets',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiHeadset' in icon ? icon['mdiHeadset' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_SUPPORT_TICKETS'
label: 'Administration',
icon: icon.mdiShieldAccountOutline,
menu: [
{
href: '/users/users-list',
label: 'Users',
icon: icon.mdiAccountGroup,
permissions: 'READ_USERS'
},
{
href: '/roles/roles-list',
label: 'Roles',
icon: icon.mdiShieldAccountVariantOutline,
permissions: 'READ_ROLES'
},
{
href: '/permissions/permissions-list',
label: 'Permissions',
icon: icon.mdiShieldAccountOutline,
permissions: 'READ_PERMISSIONS'
},
]
},
{
href: '/profile',
label: 'Profile',
icon: icon.mdiAccountCircle,
},
{
href: '/api-docs',
target: '_blank',
label: 'Swagger API',
icon: icon.mdiFileCode,
permissions: 'READ_API_DOCS'
},
]
export default menuAside
export default menuAside

View File

@ -149,9 +149,9 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
setStepsEnabled(false);
};
const title = 'AI App Draft'
const description = "Crypto trading platform inspired by OKX with exchange, wallets, orders, and KYC."
const url = "https://flatlogic.com/"
const title = 'ADML Exchange'
const description = "Professional crypto trading platform with spot, perpetual contracts, and second contracts."
const url = "https://adml-exchange.com/"
const image = "https://project-screens.s3.amazonaws.com/screenshots/37805/app-hero-20260125-125615.png"
const imageWidth = '1920'
const imageHeight = '960'
@ -164,7 +164,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
<meta name="description" content={description} />
<meta property="og:url" content={url} />
<meta property="og:site_name" content="https://flatlogic.com/" />
<meta property="og:site_name" content="ADML EXCHANGE" />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
@ -198,4 +198,4 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
)
}
export default appWithTranslation(MyApp);
export default appWithTranslation(MyApp);

View File

@ -93,16 +93,21 @@ const Dashboard = () => {
<>
<Head>
<title>
{getPageTitle('Overview')}
{getPageTitle('Exchange Overview')}
</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton
icon={icon.mdiChartTimelineVariant}
title='Overview'
title='Exchange Overview'
main>
{''}
</SectionTitleLineWithButton>
<div className="bg-blue-600/10 border border-blue-500/20 rounded-2xl p-6 mb-8">
<h2 className="text-2xl font-bold mb-2">Welcome back, {currentUser?.firstName || 'Trader'}!</h2>
<p className="text-gray-500 dark:text-gray-400">Monitor your assets, track orders, and manage your exchange operations from this central hub.</p>
</div>
{hasPermission(currentUser, 'CREATE_ROLES') && <WidgetCreator
currentUser={currentUser}
@ -523,4 +528,4 @@ Dashboard.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>
}
export default Dashboard
export default Dashboard

View File

@ -0,0 +1,219 @@
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 ExchangePage = () => {
const { t } = useTranslation('common');
const [mounted, setMounted] = useState(false);
const [currentTab, setCurrentTab] = useState('Open Orders');
useEffect(() => {
setMounted(true);
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": "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 (
<>
<Head>
<title>{getPageTitle(t('exchange.title', { defaultValue: 'Spot Trading' }))}</title>
</Head>
<div className="flex flex-col h-[calc(100vh-64px)] overflow-hidden bg-[#000000] text-white">
{/* Trading Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-white/5 bg-[#080808] backdrop-blur-xl">
<div className="flex items-center space-x-8">
<div className="flex items-center space-x-3 group cursor-pointer">
<div className="w-10 h-10 bg-orange-500/10 rounded-xl flex items-center justify-center group-hover:bg-orange-500/20 transition-colors">
<BaseIcon path={icon.mdiBitcoin} size={28} className="text-orange-500" />
</div>
<div>
<div className="text-lg font-black tracking-tighter leading-none">BTC/USDT</div>
<div className="text-[10px] font-black text-emerald-500 uppercase mt-1 tracking-widest">{t('exchange.header.spot', { defaultValue: 'Spot' })}</div>
</div>
</div>
<div className="flex items-center space-x-8">
<div>
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('exchange.header.last_price', { defaultValue: 'Last Price' })}</div>
<div className="text-emerald-500 text-lg font-black tracking-tighter">43,123.45</div>
</div>
<div className="hidden sm:block">
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('exchange.header.change', { defaultValue: '24h Change' })}</div>
<div className="text-emerald-500 text-sm font-black">+2.45%</div>
</div>
<div className="hidden lg:block">
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('exchange.header.high', { defaultValue: '24h High' })}</div>
<div className="text-white text-sm font-black">44,500.00</div>
</div>
<div className="hidden lg:block">
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('exchange.header.low', { defaultValue: '24h Low' })}</div>
<div className="text-white text-sm font-black">42,000.00</div>
</div>
<div className="hidden xl:block">
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('exchange.header.volume', { defaultValue: '24h Volume(BTC)' })}</div>
<div className="text-white text-sm font-black">32,123.45</div>
</div>
</div>
</div>
<div className="flex items-center space-x-4">
<BaseButton color="info" label={t('exchange.header.deposit', { defaultValue: 'Deposit' })} small className="font-black px-6 rounded-xl" />
</div>
</div>
<div className="flex flex-1 overflow-hidden">
{/* Main Chart Area */}
<div className="flex-1 flex flex-col border-r border-white/5">
<div id="tradingview_chart" className="flex-1"></div>
{/* Orders Tabs */}
<div className="h-72 border-t border-white/5 bg-[#080808] overflow-hidden flex flex-col">
<div className="flex border-b border-white/5 bg-white/[0.02]">
{[
t('exchange.tabs.open_orders', { defaultValue: 'Open Orders' }),
t('exchange.tabs.order_history', { defaultValue: 'Order History' }),
t('exchange.tabs.trade_history', { defaultValue: 'Trade History' }),
t('exchange.tabs.assets', { defaultValue: 'Assets' })
].map((tab) => (
<button
key={tab}
onClick={() => setCurrentTab(tab)}
className={`px-8 py-4 text-[10px] font-black uppercase tracking-[0.2em] transition-all ${currentTab === tab ? 'text-blue-500 border-b-2 border-blue-500 bg-blue-500/5' : 'text-gray-500 hover:text-white'}`}
>
{tab}
</button>
))}
</div>
<div className="flex-1 flex flex-col items-center justify-center p-8 text-center">
<div className="w-16 h-16 bg-white/[0.02] rounded-full flex items-center justify-center mb-4">
<BaseIcon path={icon.mdiInboxOutline} size={32} className="text-gray-700" />
</div>
<p className="text-gray-600 text-xs font-black uppercase tracking-widest italic">
{t('exchange.no_records', { defaultValue: 'No active records found' })}
</p>
</div>
</div>
</div>
{/* Order Book & Trade Panel */}
<div className="w-[340px] flex flex-col bg-[#080808]">
{/* Order Book */}
<div className="flex-1 border-b border-white/5 p-4 overflow-hidden flex flex-col">
<div className="flex items-center justify-between mb-4">
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-gray-500">{t('exchange.orderbook.title', { defaultValue: 'Order Book' })}</h4>
<div className="flex space-x-1">
<div className="w-4 h-4 bg-emerald-500/20 rounded-sm"></div>
<div className="w-4 h-4 bg-rose-500/20 rounded-sm"></div>
<div className="w-4 h-4 bg-white/10 rounded-sm"></div>
</div>
</div>
<div className="grid grid-cols-2 text-[10px] font-black uppercase text-gray-600 mb-2 px-2">
<span>{t('exchange.orderbook.price', { defaultValue: 'Price' })} (USDT)</span>
<span className="text-right">{t('exchange.orderbook.amount', { defaultValue: 'Amount' })} (BTC)</span>
</div>
<div className="flex-1 overflow-y-auto space-y-[2px] font-mono text-[11px] font-bold">
{[...Array(12)].map((_, i) => (
<div key={`ask-${i}`} className="flex justify-between text-rose-500 hover:bg-rose-500/10 px-2 py-0.5 rounded cursor-pointer transition-colors relative group">
<div className="absolute inset-y-0 right-0 bg-rose-500/10 transition-all duration-500" style={{ width: `${Math.random() * 100}%` }}></div>
<span className="relative z-10">43,{(123 + (12-i)*5).toString().padStart(3, '0')}.45</span>
<span className="relative z-10 text-gray-400">{(Math.random() * 2).toFixed(4)}</span>
</div>
))}
<div className="py-4 px-2 my-2 border-y border-white/5 bg-white/[0.01]">
<div className="text-xl font-black text-emerald-500 tracking-tighter">43,123.45</div>
<div className="text-[10px] text-gray-500 font-black uppercase tracking-widest mt-0.5"> $43,123.45</div>
</div>
{[...Array(12)].map((_, i) => (
<div key={`bid-${i}`} className="flex justify-between text-emerald-500 hover:bg-emerald-500/10 px-2 py-0.5 rounded cursor-pointer transition-colors relative group">
<div className="absolute inset-y-0 right-0 bg-emerald-500/10 transition-all duration-500" style={{ width: `${Math.random() * 100}%` }}></div>
<span className="relative z-10">43,{(123 - i*5).toString().padStart(3, '0')}.45</span>
<span className="relative z-10 text-gray-400">{(Math.random() * 2).toFixed(4)}</span>
</div>
))}
</div>
</div>
{/* Trade Panel */}
<div className="p-6 bg-black/40">
<div className="flex bg-white/5 p-1 rounded-xl mb-6">
<button className="flex-1 py-2.5 bg-emerald-500 text-black font-black uppercase text-[10px] tracking-widest rounded-lg transition-all shadow-lg shadow-emerald-500/20">{t('exchange.panel.buy', { defaultValue: 'Buy' })}</button>
<button className="flex-1 py-2.5 text-gray-500 font-black uppercase text-[10px] tracking-widest rounded-lg hover:text-white transition-all">{t('exchange.panel.sell', { defaultValue: 'Sell' })}</button>
</div>
<div className="space-y-4">
<div className="flex justify-between text-[10px] font-black uppercase tracking-widest text-gray-500 mb-1 px-1">
<span>{t('exchange.panel.type', { defaultValue: 'Order Type' })}</span>
<span className="text-blue-500 cursor-pointer">{t('exchange.panel.market', { defaultValue: 'Market' })}</span>
</div>
<div className="relative group">
<span className="absolute left-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600 group-focus-within:text-blue-500 transition-colors">{t('exchange.panel.price', { defaultValue: 'Price' })}</span>
<input type="text" defaultValue="43123.45" className="w-full bg-[#111111] border border-white/10 rounded-xl pl-16 pr-14 py-3 text-white text-xs font-black focus:border-blue-500/50 transition-all outline-none" />
<span className="absolute right-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600">USDT</span>
</div>
<div className="relative group">
<span className="absolute left-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600 group-focus-within:text-blue-500 transition-colors">{t('exchange.panel.amount', { defaultValue: 'Amount' })}</span>
<input type="text" placeholder="0.00" className="w-full bg-[#111111] border border-white/10 rounded-xl pl-16 pr-14 py-3 text-white text-xs font-black focus:border-blue-500/50 transition-all outline-none" />
<span className="absolute right-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600">BTC</span>
</div>
{/* Percentage Buttons */}
<div className="grid grid-cols-4 gap-2">
{[25, 50, 75, 100].map(p => (
<button key={p} className="py-1.5 bg-white/5 text-[9px] font-black rounded-lg hover:bg-white/10 text-gray-500 hover:text-white transition-all">{p}%</button>
))}
</div>
<div className="flex justify-between text-[10px] font-black uppercase tracking-widest text-gray-600 px-1 pt-2">
<span>{t('exchange.panel.available', { defaultValue: 'Available' })}</span>
<span className="text-white">0.00 USDT</span>
</div>
<BaseButton
color="info"
label={`${t('exchange.panel.buy', { defaultValue: 'BUY' })} BTC`}
className="w-full py-4 font-black bg-emerald-500 border-none text-black rounded-2xl mt-4 shadow-xl shadow-emerald-500/10 hover:scale-[1.02] active:scale-95 transition-all uppercase tracking-[0.2em] text-xs"
/>
</div>
</div>
</div>
</div>
</div>
</>
);
};
ExchangePage.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};
export default ExchangePage;

View File

@ -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) => (
<div
className='hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'
style={{
backgroundImage: `${
image
? `url(${image?.src?.original})`
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
}`,
backgroundSize: 'cover',
backgroundPosition: 'left center',
backgroundRepeat: 'no-repeat',
}}
>
<div className='flex justify-center w-full bg-blue-300/20'>
<a
className='text-[8px]'
href={image?.photographer_url}
target='_blank'
rel='noreferrer'
>
Photo by {image?.photographer} on Pexels
</a>
</div>
</div>
);
const videoBlock = (video) => {
if (video?.video_files?.length > 0) {
return (
<div className='hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'>
<video
className='absolute top-0 left-0 w-full h-full object-cover'
autoPlay
loop
muted
>
<source src={video?.video_files[0]?.link} type='video/mp4'/>
Your browser does not support the video tag.
</video>
<div className='flex justify-center w-full bg-blue-300/20 z-10'>
<a
className='text-[8px]'
href={video?.user?.url}
target='_blank'
rel='noreferrer'
>
Video by {video.user.name} on Pexels
</a>
</div>
</div>)
}
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 (
<div
style={
contentPosition === 'background'
? {
backgroundImage: `${
illustrationImage
? `url(${illustrationImage.src?.original})`
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
}`,
backgroundSize: 'cover',
backgroundPosition: 'left center',
backgroundRepeat: 'no-repeat',
}
: {}
}
>
<div className="min-h-screen bg-[#000000] text-white selection:bg-blue-500/30">
<Head>
<title>{getPageTitle('Starter Page')}</title>
<title>{getPageTitle(t('landing.hero.title', { defaultValue: 'ADML Exchange | The Worlds Leading Crypto Exchange' }))}</title>
</Head>
<SectionFullScreen bg='violet'>
<div
className={`flex ${
contentPosition === 'right' ? 'flex-row-reverse' : 'flex-row'
} min-h-screen w-full`}
>
{contentType === 'image' && contentPosition !== 'background'
? imageBlock(illustrationImage)
: null}
{contentType === 'video' && contentPosition !== 'background'
? videoBlock(illustrationVideo)
: null}
<div className='flex items-center justify-center flex-col space-y-4 w-full lg:w-full'>
<CardBox className='w-full md:w-3/5 lg:w-2/3'>
<CardBoxComponentTitle title="Welcome to your AI App Draft app!"/>
<div className="space-y-3">
<p className='text-center text-gray-500'>This is a React.js/Node.js app generated by the <a className={`${textColor}`} href="https://flatlogic.com/generator">Flatlogic Web App Generator</a></p>
<p className='text-center text-gray-500'>For guides and documentation please check
your local README.md and the <a className={`${textColor}`} href="https://flatlogic.com/documentation">Flatlogic documentation</a></p>
</div>
<BaseButtons>
<BaseButton
href='/login'
label='Login'
color='info'
className='w-full'
/>
</BaseButtons>
</CardBox>
{/* Navbar */}
<nav className="flex items-center justify-between px-6 py-4 border-b border-white/5 bg-black/80 backdrop-blur-md sticky top-0 z-50">
<div className="flex items-center space-x-10">
<Link href="/" className="flex items-center space-x-2 group">
<Logo className="text-white" />
</Link>
<div className="hidden lg:flex space-x-8 text-[14px] font-bold text-gray-400 uppercase tracking-tight">
<Link href="/markets" className="hover:text-white transition-colors">{t('nav.markets', { defaultValue: 'Markets' })}</Link>
<Link href="/exchange" className="hover:text-white transition-colors">{t('nav.spot', { defaultValue: 'Spot' })}</Link>
<Link href="/perpetual" className="hover:text-white transition-colors">{t('nav.perpetual', { defaultValue: 'Perpetual' })}</Link>
<Link href="/second-contract" className="hover:text-white transition-colors">{t('nav.options', { defaultValue: 'Options' })}</Link>
</div>
</div>
</div>
</SectionFullScreen>
<div className='bg-black text-white flex flex-col text-center justify-center md:flex-row'>
<p className='py-6 text-sm'>© 2026 <span>{title}</span>. All rights reserved</p>
<Link className='py-6 ml-4 text-sm' href='/privacy-policy/'>
Privacy Policy
</Link>
</div>
<div className="flex items-center space-x-6">
<LanguageSwitcher />
<Link href="/login" className="text-[14px] font-bold uppercase hover:text-blue-500 transition-colors hidden sm:block">{t('login.title', { defaultValue: 'Log in' })}</Link>
<BaseButton href="/register" label={t('register.title', { defaultValue: 'Sign up' })} color="info" className="px-6 font-bold" roundedFull />
</div>
</nav>
{/* Hero Section */}
<section className="relative pt-20 pb-32 overflow-hidden">
<div className="container mx-auto px-6 relative z-10 text-center">
<div className="inline-flex items-center space-x-2 bg-blue-600/10 border border-blue-500/20 px-4 py-1.5 rounded-full text-blue-400 text-xs font-black mb-8 animate-pulse tracking-widest uppercase">
<span className="w-2 h-2 bg-blue-500 rounded-full"></span>
<span>{t('landing.hero.badge', { defaultValue: 'Trusted by 20M+ Users Globally' })}</span>
</div>
<h1 className="text-5xl md:text-8xl font-black mb-6 leading-tight tracking-tighter uppercase max-w-5xl mx-auto">
{t('landing.hero.title_part1', { defaultValue: 'Trade The Future' })} <br />
<span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-500 via-emerald-400 to-blue-500 bg-[length:200%_auto] animate-gradient-x">
{t('landing.hero.title_highlight', { defaultValue: 'With ADML' })}
</span>
</h1>
<p className="text-lg md:text-xl text-gray-400 mb-12 max-w-2xl mx-auto leading-relaxed font-medium">
{t('landing.hero.subtitle', { defaultValue: 'Securely buy, sell and trade over 400+ cryptocurrencies with low fees and institutional-grade security.' })}
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 max-w-lg mx-auto mb-20">
<input
type="text"
placeholder={t('landing.hero.input_placeholder', { defaultValue: 'Email / Phone number' })}
className="w-full sm:flex-1 bg-white/5 border border-white/10 rounded-2xl px-6 py-4 text-white focus:outline-none focus:border-blue-500 transition-all text-lg font-bold backdrop-blur-sm"
/>
<BaseButton href="/register" label={t('landing.hero.cta', { defaultValue: 'Get Started' })} color="info" className="w-full sm:w-auto px-10 py-4 h-[60px] text-lg font-black rounded-2xl shadow-2xl shadow-blue-600/20" />
</div>
{/* Quick Stats */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 max-w-4xl mx-auto py-12 border-y border-white/5 bg-white/[0.01] rounded-[40px]">
{[
{ label: '24h Vol', value: '$12.4B' },
{ label: 'Users', value: '25M+' },
{ label: 'Assets', value: '450+' },
{ label: 'Uptime', value: '99.99%' },
].map((stat, i) => (
<div key={i} className="text-center">
<div className="text-3xl font-black text-white mb-1 tracking-tighter">{stat.value}</div>
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest">{t(`landing.stats.${stat.label.toLowerCase().replace(' ', '_')}`, { defaultValue: stat.label })}</div>
</div>
))}
</div>
</div>
{/* Background Decorative Elements */}
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full -z-10 pointer-events-none">
<div className="absolute top-40 left-10 w-64 h-64 bg-blue-600/10 rounded-full blur-[120px]"></div>
<div className="absolute bottom-20 right-10 w-96 h-96 bg-emerald-500/5 rounded-full blur-[150px]"></div>
</div>
</section>
{/* Feature Sections (admlplus style) */}
<section className="py-24 bg-[#050505]">
<div className="container mx-auto px-6">
<div className="grid md:grid-cols-3 gap-12">
<div className="p-8 bg-white/[0.02] border border-white/5 rounded-[32px] hover:bg-white/[0.04] transition-all group">
<div className="w-16 h-16 bg-blue-600/10 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
<BaseIcon path={icon.mdiShieldLock} size={32} className="text-blue-500" />
</div>
<h3 className="text-2xl font-black mb-4 uppercase tracking-tighter">{t('landing.features.security.title', { defaultValue: 'Security First' })}</h3>
<p className="text-gray-500 font-medium leading-relaxed">
{t('landing.features.security.desc', { defaultValue: 'Cold storage, multi-sig wallets, and 2FA protection for all assets. Your security is our priority.' })}
</p>
</div>
<div className="p-8 bg-white/[0.02] border border-white/5 rounded-[32px] hover:bg-white/[0.04] transition-all group">
<div className="w-16 h-16 bg-emerald-600/10 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
<BaseIcon path={icon.mdiLightningBolt} size={32} className="text-emerald-500" />
</div>
<h3 className="text-2xl font-black mb-4 uppercase tracking-tighter">{t('landing.features.speed.title', { defaultValue: 'Instant Execution' })}</h3>
<p className="text-gray-500 font-medium leading-relaxed">
{t('landing.features.speed.desc', { defaultValue: 'Our high-performance matching engine handles 1M+ transactions per second with sub-millisecond latency.' })}
</p>
</div>
<div className="p-8 bg-white/[0.02] border border-white/5 rounded-[32px] hover:bg-white/[0.04] transition-all group">
<div className="w-16 h-16 bg-purple-600/10 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
<BaseIcon path={icon.mdiLifebuoy} size={32} className="text-purple-500" />
</div>
<h3 className="text-2xl font-black mb-4 uppercase tracking-tighter">{t('landing.features.support.title', { defaultValue: '24/7 Support' })}</h3>
<p className="text-gray-500 font-medium leading-relaxed">
{t('landing.features.support.desc', { defaultValue: 'Global customer support available in 12 languages around the clock to assist you with any issues.' })}
</p>
</div>
</div>
</div>
</section>
{/* Market Table */}
<section className="py-24">
<div className="container mx-auto px-6">
<div className="flex flex-col md:flex-row items-end justify-between mb-12 gap-6">
<div>
<h2 className="text-4xl md:text-5xl font-black tracking-tighter uppercase mb-4">{t('landing.markets.title', { defaultValue: 'Market Trends' })}</h2>
<div className="flex space-x-6 text-sm font-bold text-gray-500">
<button className="text-blue-500 border-b-2 border-blue-500 pb-1 uppercase tracking-wider">{t('landing.markets.tab.popular', { defaultValue: 'Popular' })}</button>
<button className="hover:text-white uppercase tracking-wider">{t('landing.markets.tab.new', { defaultValue: 'New Listings' })}</button>
<button className="hover:text-white uppercase tracking-wider">{t('landing.markets.tab.gainers', { defaultValue: 'Top Gainers' })}</button>
</div>
</div>
<Link href="/markets" className="text-blue-500 font-black uppercase text-xs tracking-widest hover:text-white transition-colors">
{t('landing.markets.view_all', { defaultValue: 'View All Markets' })}
</Link>
</div>
<div className="bg-[#080808] border border-white/5 rounded-[40px] overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full text-left border-collapse">
<thead className="bg-white/[0.02]">
<tr className="text-[10px] font-black uppercase tracking-[0.2em] text-gray-500 border-b border-white/5">
<th className="px-8 py-6">{t('landing.markets.col.asset', { defaultValue: 'Asset' })}</th>
<th className="px-8 py-6">{t('landing.markets.col.price', { defaultValue: 'Price' })}</th>
<th className="px-8 py-6">{t('landing.markets.col.change', { defaultValue: '24h Change' })}</th>
<th className="px-8 py-6 hidden lg:table-cell">{t('landing.markets.col.volume', { defaultValue: 'Volume' })}</th>
<th className="px-8 py-6 text-right">{t('landing.markets.col.action', { defaultValue: 'Action' })}</th>
</tr>
</thead>
<tbody className="divide-y divide-white/5">
{marketData.map((coin) => (
<tr key={coin.symbol} className="hover:bg-white/[0.02] transition-colors group">
<td className="px-8 py-6">
<div className="flex items-center space-x-4">
<div className="w-10 h-10 bg-white/5 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform">
<BaseIcon path={coin.icon} size={24} className="text-blue-500" />
</div>
<div>
<div className="font-black text-lg leading-none">{coin.label}</div>
<div className="text-[10px] text-gray-500 font-black uppercase mt-1">{coin.name}</div>
</div>
</div>
</td>
<td className="px-8 py-6 font-black text-lg tracking-tight">${coin.price}</td>
<td className={`px-8 py-6 font-black text-lg ${coin.color}`}>{coin.change}</td>
<td className="px-8 py-6 hidden lg:table-cell">
<div className="font-bold text-gray-500">$2.4B</div>
</td>
<td className="px-8 py-6 text-right">
<BaseButton href="/exchange" label={t('landing.markets.trade_btn', { defaultValue: 'Trade' })} color="info" small className="font-black px-6 rounded-xl" />
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</section>
{/* App Download Section (admlplus style) */}
<section className="py-24 bg-[#080808]">
<div className="container mx-auto px-6">
<div className="flex flex-col lg:flex-row items-center gap-20">
<div className="flex-1">
<h2 className="text-4xl md:text-6xl font-black mb-8 leading-tight tracking-tighter uppercase">
{t('landing.app.title', { defaultValue: 'Trade Anywhere, Anytime.' })}
</h2>
<p className="text-lg text-gray-400 mb-12 font-medium leading-relaxed">
{t('landing.app.desc', { defaultValue: 'Stay connected to the markets with our professional mobile app. Available on iOS, Android, and Web.' })}
</p>
<div className="grid grid-cols-2 gap-4">
<div className="flex items-center space-x-4 p-4 bg-white/5 border border-white/5 rounded-2xl hover:bg-white/10 transition-colors cursor-pointer group">
<BaseIcon path={icon.mdiApple} size={32} />
<div>
<div className="text-[10px] font-black text-gray-500 uppercase leading-none mb-1">Download on</div>
<div className="font-black">App Store</div>
</div>
</div>
<div className="flex items-center space-x-4 p-4 bg-white/5 border border-white/5 rounded-2xl hover:bg-white/10 transition-colors cursor-pointer group">
<BaseIcon path={icon.mdiGooglePlay} size={32} />
<div>
<div className="text-[10px] font-black text-gray-500 uppercase leading-none mb-1">Get it on</div>
<div className="font-black">Google Play</div>
</div>
</div>
</div>
<div className="mt-12 flex items-center space-x-6 p-6 bg-blue-600/10 border border-blue-500/20 rounded-3xl">
<div className="w-24 h-24 bg-white p-2 rounded-xl">
{/* Mock QR Code */}
<div className="w-full h-full bg-black flex items-center justify-center">
<Logo className="scale-50 opacity-50" />
</div>
</div>
<div>
<h4 className="font-black text-blue-400 uppercase tracking-tighter mb-1">{t('landing.app.qr_title', { defaultValue: 'Scan to download' })}</h4>
<p className="text-xs text-gray-500 font-bold">{t('landing.app.qr_desc', { defaultValue: 'Instant access to ADML features on your mobile device.' })}</p>
</div>
</div>
</div>
<div className="flex-1 relative">
<div className="relative z-10 mx-auto w-full max-w-[320px] aspect-[9/19] bg-[#111111] border-[8px] border-[#222222] rounded-[40px] shadow-[0_0_100px_rgba(37,99,235,0.2)] overflow-hidden">
<div className="h-6 w-32 bg-[#222222] absolute top-0 left-1/2 -translate-x-1/2 rounded-b-2xl"></div>
<div className="p-6 pt-10">
<Logo className="scale-75 origin-left mb-8" />
<div className="space-y-4">
<div className="h-24 bg-white/5 rounded-2xl p-4 flex flex-col justify-between">
<div className="text-[10px] font-black text-gray-500 uppercase">Available Balance</div>
<div className="text-2xl font-black">$45,231.50</div>
</div>
<div className="grid grid-cols-2 gap-2">
<div className="h-10 bg-blue-600 rounded-xl flex items-center justify-center text-[10px] font-black uppercase">Deposit</div>
<div className="h-10 bg-white/10 rounded-xl flex items-center justify-center text-[10px] font-black uppercase">Withdraw</div>
</div>
<div className="space-y-2 pt-4">
{[1,2,3].map(i => (
<div key={i} className="flex items-center justify-between p-3 bg-white/5 rounded-xl">
<div className="flex items-center space-x-2">
<div className="w-6 h-6 bg-white/10 rounded-full"></div>
<div className="w-12 h-2 bg-white/20 rounded"></div>
</div>
<div className="w-16 h-2 bg-emerald-500/20 rounded"></div>
</div>
))}
</div>
</div>
</div>
</div>
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[140%] h-[140%] bg-blue-600/10 rounded-full blur-[100px] -z-10"></div>
</div>
</div>
</div>
</section>
{/* CTA Section */}
<section className="py-32 relative overflow-hidden text-center">
<div className="container mx-auto px-6 relative z-10">
<h2 className="text-5xl md:text-7xl font-black mb-8 leading-tight tracking-tighter uppercase">{t('landing.cta.title', { defaultValue: 'Start Your Trade Now' })}</h2>
<p className="text-xl text-gray-500 mb-12 max-w-2xl mx-auto font-medium">{t('landing.cta.desc', { defaultValue: 'Join the most reliable crypto exchange in the world.' })}</p>
<div className="flex flex-col sm:flex-row justify-center gap-4">
<BaseButton href="/register" label={t('landing.cta.btn_signup', { defaultValue: 'Create Account' })} color="info" className="px-12 py-5 text-xl font-black rounded-2xl" />
<BaseButton href="/login" label={t('landing.cta.btn_login', { defaultValue: 'Login Demo' })} color="whiteDark" className="px-12 py-5 text-xl font-black border border-white/10 rounded-2xl" />
</div>
</div>
</section>
{/* Footer */}
<footer className="py-24 border-t border-white/5 bg-black">
<div className="container mx-auto px-6">
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-12 mb-20">
<div className="col-span-2 lg:col-span-1">
<Link href="/" className="flex items-center space-x-2 mb-8">
<Logo className="text-white" />
</Link>
<p className="text-gray-500 text-xs leading-relaxed max-w-xs font-bold uppercase tracking-widest opacity-60">
{t('footer.about', { defaultValue: 'Professional and secure digital asset trading platform.' })}
</p>
</div>
<div>
<h4 className="text-white font-black uppercase text-xs tracking-[0.2em] mb-8">{t('footer.section.about', { defaultValue: 'About' })}</h4>
<ul className="space-y-4 text-xs font-black uppercase tracking-widest text-gray-600">
<li><Link href="/login" className="hover:text-blue-500 transition-colors">Company</Link></li>
<li><Link href="/login" className="hover:text-blue-500 transition-colors">Careers</Link></li>
<li><Link href="/login" className="hover:text-blue-500 transition-colors">News</Link></li>
</ul>
</div>
<div>
<h4 className="text-white font-black uppercase text-xs tracking-[0.2em] mb-8">{t('footer.section.product', { defaultValue: 'Product' })}</h4>
<ul className="space-y-4 text-xs font-black uppercase tracking-widest text-gray-600">
<li><Link href="/exchange" className="hover:text-blue-500 transition-colors">Spot</Link></li>
<li><Link href="/perpetual" className="hover:text-blue-500 transition-colors">Perpetual</Link></li>
<li><Link href="/second-contract" className="hover:text-blue-500 transition-colors">Options</Link></li>
</ul>
</div>
<div>
<h4 className="text-white font-black uppercase text-xs tracking-[0.2em] mb-8">{t('footer.section.support', { defaultValue: 'Support' })}</h4>
<ul className="space-y-4 text-xs font-black uppercase tracking-widest text-gray-600">
<li><Link href="/login" className="hover:text-blue-500 transition-colors">Help Center</Link></li>
<li><Link href="/login" className="hover:text-blue-500 transition-colors">API</Link></li>
<li><Link href="/login" className="hover:text-blue-500 transition-colors">Fees</Link></li>
</ul>
</div>
<div>
<h4 className="text-white font-black uppercase text-xs tracking-[0.2em] mb-8">{t('footer.section.legal', { defaultValue: 'Legal' })}</h4>
<ul className="space-y-4 text-xs font-black uppercase tracking-widest text-gray-600">
<li><Link href="/privacy-policy" className="hover:text-blue-500 transition-colors">Privacy</Link></li>
<li><Link href="/terms-of-use" className="hover:text-blue-500 transition-colors">Terms</Link></li>
</ul>
</div>
</div>
<div className="pt-12 border-t border-white/5 flex flex-col md:flex-row justify-between items-center gap-6">
<p className="text-[10px] font-black text-gray-600 uppercase tracking-[0.3em]">
&copy; 2026 ADML EXCHANGE. ALL RIGHTS RESERVED.
</p>
<div className="flex space-x-8">
<BaseIcon path={icon.mdiTwitter} size={20} className="text-gray-600 hover:text-white transition-colors cursor-pointer" />
<BaseIcon path={icon.mdiSend} size={20} className="text-gray-600 hover:text-white transition-colors cursor-pointer" />
<BaseIcon path={icon.mdiForum} size={20} className="text-gray-600 hover:text-white transition-colors cursor-pointer" />
</div>
</div>
</div>
</footer>
<style jsx global>{`
@keyframes gradient-x {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.animate-gradient-x {
animation: gradient-x 5s ease infinite;
}
`}</style>
</div>
);
}
Starter.getLayout = function getLayout(page: ReactElement) {
LandingPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutGuest>{page}</LayoutGuest>;
};
};

View File

@ -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() {
</Head>
<SectionFullScreen bg='violet'>
<div className={`flex ${contentPosition === 'right' ? 'flex-row-reverse' : 'flex-row'} min-h-screen w-full`}>
<div className={`flex ${contentPosition === 'right' ? 'flex-row-reverse' : 'flex-row'} min-h-screen w-full bg-black/40 backdrop-blur-sm`}>
{contentType === 'image' && contentPosition !== 'background' ? imageBlock(illustrationImage) : null}
{contentType === 'video' && contentPosition !== 'background' ? videoBlock(illustrationVideo) : null}
<div className='flex items-center justify-center flex-col space-y-4 w-full lg:w-full'>
<CardBox id="loginRoles" className='w-full md:w-3/5 lg:w-2/3'>
<h2 className="text-4xl font-semibold my-4">{title}</h2>
<div className='flex flex-row text-gray-500 justify-between'>
<div>
<p className='mb-2'>Use{' '}
<code className={`cursor-pointer ${textColor} `}
data-password="4b8a182c"
onClick={(e) => setLogin(e.target)}>admin@flatlogic.com</code>{' / '}
<code className={`${textColor}`}>4b8a182c</code>{' / '}
to login as Admin</p>
<p>Use <code
className={`cursor-pointer ${textColor} `}
data-password="ed8b688f77aa"
onClick={(e) => setLogin(e.target)}>client@hello.com</code>{' / '}
<code className={`${textColor}`}>ed8b688f77aa</code>{' / '}
to login as User</p>
</div>
<div>
<BaseIcon
className={`${iconsColor}`}
w='w-16'
h='h-16'
size={48}
path={mdiInformation}
/>
</div>
<CardBox className='w-full md:w-3/5 lg:w-1/2 shadow-2xl bg-white/90 dark:bg-dark-900/90'>
<div className="flex flex-col items-center mb-8">
<Logo className="text-3xl mb-4" />
<h2 className="text-2xl font-black tracking-tight uppercase">Welcome to ADML</h2>
<p className="text-gray-500 text-sm font-medium">Please sign in to continue trading</p>
</div>
</CardBox>
<CardBox className='w-full md:w-3/5 lg:w-2/3'>
<Formik
initialValues={initialValues}
enableReinitialize
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<Form className="space-y-4">
<FormField
label='Login'
help='Please enter your login'>
<Field name='email' />
label='Email / Account'
help='Enter your registered email'>
<Field name='email' placeholder="example@adml.com" />
</FormField>
<div className='relative'>
<FormField
label='Password'
help='Please enter your password'>
<Field name='password' type={showPassword ? 'text' : 'password'} />
help='Enter your password'>
<Field name='password' type={showPassword ? 'text' : 'password'} placeholder="••••••••" />
</FormField>
<div
className='absolute bottom-8 right-0 pr-3 flex items-center cursor-pointer'
@ -226,45 +208,59 @@ export default function Login() {
</div>
</div>
<div className={'flex justify-between'}>
<FormCheckRadio type='checkbox' label='Remember'>
<div className={'flex justify-between items-center px-1'}>
<FormCheckRadio type='checkbox' label='Stay logged in'>
<Field type='checkbox' name='remember' />
</FormCheckRadio>
<Link className={`${textColor} text-blue-600`} href={'/forgot'}>
<Link className={`${textColor} text-sm font-bold`} href={'/forgot'}>
Forgot password?
</Link>
</div>
<BaseDivider />
<BaseButtons>
<BaseButtons vertical className="space-y-3">
<BaseButton
className={'w-full'}
className={'w-full py-3 font-black text-lg'}
type='submit'
label={isFetching ? 'Loading...' : 'Login'}
label={isFetching ? 'Verifying...' : 'Sign In'}
color='info'
disabled={isFetching}
/>
<BaseButton
className={'w-full py-3 font-bold border-2 border-blue-600/50 hover:bg-blue-600 hover:text-white transition-all'}
type='button'
onClick={handleDemoLogin}
label='Demo Account Login'
outline
color='info'
icon={mdiAccountCircle}
/>
</BaseButtons>
<br />
<p className={'text-center'}>
<p className={'text-center mt-6 text-sm font-medium text-gray-500'}>
Dont have an account yet?{' '}
<Link className={`${textColor}`} href={'/register'}>
New Account
<Link className={`${textColor} font-black underline decoration-2 underline-offset-4`} href={'/register'}>
Create Account
</Link>
</p>
</Form>
</Formik>
</CardBox>
<div className="bg-white/10 backdrop-blur-md rounded-2xl p-4 border border-white/10 text-[10px] text-gray-400 font-bold uppercase tracking-widest text-center max-w-md">
Warning: Please verify the URL is adml-exchange.com to prevent phishing.
</div>
</div>
</div>
</SectionFullScreen>
<div className='bg-black text-white flex flex-col text-center justify-center md:flex-row'>
<p className='py-6 text-sm'>© 2026 <span>{title}</span>. © All rights reserved</p>
<Link className='py-6 ml-4 text-sm' href='/privacy-policy/'>
Privacy Policy
</Link>
<div className='bg-black text-white flex flex-col text-center justify-center md:flex-row py-8 border-t border-white/5'>
<p className='text-sm font-bold opacity-60 uppercase tracking-widest'>© 2026 ADML EXCHANGE. ALL RIGHTS RESERVED.</p>
<div className="flex space-x-6 md:ml-12 mt-4 md:mt-0">
<Link className='text-xs font-black uppercase tracking-widest hover:text-blue-500' href='/privacy-policy/'>Privacy Policy</Link>
<Link className='text-xs font-black uppercase tracking-widest hover:text-blue-500' href='/terms/'>Terms of Service</Link>
</div>
</div>
<ToastContainer />
</div>
@ -273,4 +269,4 @@ export default function Login() {
Login.getLayout = function getLayout(page: ReactElement) {
return <LayoutGuest>{page}</LayoutGuest>;
};
};

View File

@ -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<any[]>([]);
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 (
<>
<Head>
<title>{getPageTitle('Markets')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={icon.mdiChartLine} title="Markets" main>
<div className="flex space-x-2">
<BaseButton label="Spot" color="info" small />
<BaseButton label="Futures" color="whiteDark" small />
<BaseButton label="Options" color="whiteDark" small />
</div>
</SectionTitleLineWithButton>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
{marketData.slice(0, 3).map((coin) => (
<div key={coin.symbol} className="bg-white dark:bg-dark-900 border border-white/5 p-6 rounded-3xl">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center space-x-3">
<BaseIcon path={coin.icon} size={32} className="text-blue-500" />
<span className="font-black text-lg">{coin.label}/USDT</span>
</div>
<span className={`text-sm font-bold ${coin.isPositive ? 'text-emerald-500' : 'text-rose-500'}`}>{coin.change}</span>
</div>
<div className="text-3xl font-black">${coin.price}</div>
<div className="text-xs text-gray-500 font-bold mt-2 uppercase">24h Volume: {coin.volume}</div>
</div>
))}
</div>
<div className="bg-white dark:bg-dark-900 border border-white/5 rounded-3xl overflow-hidden shadow-xl">
<div className="overflow-x-auto">
<table className="w-full text-left border-collapse">
<thead>
<tr className="bg-gray-50 dark:bg-dark-800 text-gray-500 text-xs font-black uppercase tracking-widest border-b border-white/5">
<th className="px-6 py-4">Asset</th>
<th className="px-6 py-4">Price</th>
<th className="px-6 py-4">24h Change</th>
<th className="px-6 py-4">24h High/Low</th>
<th className="px-6 py-4">24h Volume</th>
<th className="px-6 py-4 text-right">Trade</th>
</tr>
</thead>
<tbody className="divide-y divide-white/5">
{marketData.map((asset) => (
<tr key={asset.symbol} className="hover:bg-gray-50 dark:hover:bg-white/[0.02] transition-colors group">
<td className="px-6 py-5">
<div className="flex items-center space-x-3">
<BaseIcon path={asset.icon} size={24} className="text-blue-500" />
<div>
<div className="font-black text-base">{asset.label}</div>
<div className="text-[10px] text-gray-500 font-bold uppercase">{asset.name}</div>
</div>
</div>
</td>
<td className="px-6 py-5">
<div className="font-black text-base">${asset.price}</div>
</td>
<td className="px-6 py-5">
<div className={`font-black ${asset.isPositive ? 'text-emerald-500' : 'text-rose-500'}`}>
{asset.change}
</div>
</td>
<td className="px-6 py-5">
<div className="text-xs font-bold text-gray-500">H: {asset.high}</div>
<div className="text-xs font-bold text-gray-500">L: {asset.low}</div>
</td>
<td className="px-6 py-5">
<div className="text-sm font-bold text-gray-400">{asset.volume} USDT</div>
</td>
<td className="px-6 py-5 text-right">
<BaseButton
href="/exchange"
label="Trade"
color="info"
small
className="font-black px-6"
/>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</SectionMain>
</>
);
};
MarketsPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutGuest>{page}</LayoutGuest>;
};
export default MarketsPage;

View File

@ -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 (
<>
<Head>
<title>{getPageTitle(t('perpetual.title', { defaultValue: 'Perpetual Trading' }))}</title>
</Head>
<div className="flex flex-col h-[calc(100vh-64px)] overflow-hidden bg-[#000000] text-white">
{/* Trading Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-white/5 bg-[#080808]">
<div className="flex items-center space-x-10">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-orange-500/10 rounded-xl flex items-center justify-center">
<BaseIcon path={icon.mdiBitcoin} size={28} className="text-orange-500" />
</div>
<div>
<div className="text-lg font-black tracking-tighter leading-none">BTC/USDT</div>
<div className="flex items-center space-x-1 mt-1">
<span className="text-[9px] font-black bg-blue-600/20 text-blue-500 px-1.5 py-0.5 rounded uppercase tracking-widest">{t('perpetual.header.perp', { defaultValue: 'Perp' })}</span>
<span className="text-[9px] font-black bg-white/5 text-gray-500 px-1.5 py-0.5 rounded uppercase tracking-widest">{leverage}x</span>
</div>
</div>
</div>
<div className="flex items-center space-x-10">
<div>
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('perpetual.header.mark_price', { defaultValue: 'Mark Price' })}</div>
<div className="text-emerald-500 text-lg font-black tracking-tighter">43,123.45</div>
</div>
<div className="hidden sm:block">
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('perpetual.header.funding', { defaultValue: 'Funding / Countdown' })}</div>
<div className="text-blue-500 text-xs font-black">0.0100% / 04:21:05</div>
</div>
<div className="hidden lg:block">
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('perpetual.header.change', { defaultValue: '24h Change' })}</div>
<div className="text-emerald-500 text-xs font-black">+2.45%</div>
</div>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="flex items-center space-x-2 bg-white/5 px-4 py-2 rounded-xl border border-white/5 cursor-pointer hover:bg-white/10 transition-all">
<span className="text-[10px] font-black text-gray-500 uppercase tracking-widest">{t('perpetual.header.margin', { defaultValue: 'Margin' })}</span>
<span className="text-xs font-black text-blue-500 uppercase">{t('perpetual.header.cross', { defaultValue: 'Cross' })}</span>
</div>
<BaseButton color="info" label={t('perpetual.header.deposit', { defaultValue: 'Deposit' })} small className="font-black px-6 rounded-xl" />
</div>
</div>
<div className="flex flex-1 overflow-hidden">
{/* Main Chart Area */}
<div className="flex-1 flex flex-col border-r border-white/5">
<div id="tradingview_chart" className="flex-1"></div>
{/* Positions/Orders Tabs */}
<div className="h-72 border-t border-white/5 bg-[#080808] overflow-hidden flex flex-col">
<div className="flex border-b border-white/5 bg-white/[0.02]">
{[
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) => (
<button
key={tab}
onClick={() => setCurrentTab(tab)}
className={`px-8 py-4 text-[10px] font-black uppercase tracking-[0.2em] transition-all ${currentTab === tab ? 'text-blue-500 border-b-2 border-blue-500 bg-blue-500/5' : 'text-gray-500 hover:text-white'}`}
>
{tab}
</button>
))}
</div>
<div className="flex-1 flex flex-col items-center justify-center p-8 text-center opacity-40">
<BaseIcon path={icon.mdiClipboardTextOutline} size={48} className="text-gray-700 mb-4" />
<p className="text-gray-600 text-[10px] font-black uppercase tracking-widest">
{t('perpetual.no_positions', { defaultValue: 'No active positions or orders' })}
</p>
</div>
</div>
</div>
{/* Trade Panel */}
<div className="w-[340px] flex flex-col bg-[#080808]">
{/* Mode Selector */}
<div className="p-6 bg-black/40 border-b border-white/5">
<div className="flex bg-white/5 p-1 rounded-xl mb-6">
<button
onClick={() => setSide('long')}
className={`flex-1 py-2.5 font-black uppercase text-[10px] tracking-widest rounded-lg transition-all ${side === 'long' ? 'bg-emerald-500 text-black shadow-lg shadow-emerald-500/20' : 'text-gray-500 hover:text-white'}`}
>
{t('perpetual.panel.long', { defaultValue: 'Open Long' })}
</button>
<button
onClick={() => setSide('short')}
className={`flex-1 py-2.5 font-black uppercase text-[10px] tracking-widest rounded-lg transition-all ${side === 'short' ? 'bg-rose-500 text-black shadow-lg shadow-rose-500/20' : 'text-gray-500 hover:text-white'}`}
>
{t('perpetual.panel.short', { defaultValue: 'Open Short' })}
</button>
</div>
<div className="space-y-4">
<div className="flex justify-between items-center text-[10px] font-black uppercase tracking-widest text-gray-500">
<span>{t('perpetual.panel.mode', { defaultValue: 'Margin Mode' })}</span>
<span className="text-blue-500 cursor-pointer hover:bg-blue-500/10 px-2 py-1 rounded transition-all">{t('perpetual.panel.cross', { defaultValue: 'Cross' })} {leverage}x</span>
</div>
<div className="relative group">
<span className="absolute left-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600 group-focus-within:text-blue-500">{t('perpetual.panel.price', { defaultValue: 'Price' })}</span>
<input type="text" defaultValue="43123.45" className="w-full bg-[#111111] border border-white/10 rounded-xl pl-16 pr-14 py-3 text-white text-xs font-black focus:border-blue-500/50 outline-none transition-all" />
<span className="absolute right-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600">USDT</span>
</div>
<div className="relative group">
<span className="absolute left-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600 group-focus-within:text-blue-500">{t('perpetual.panel.amount', { defaultValue: 'Amount' })}</span>
<input type="text" placeholder="0.00" className="w-full bg-[#111111] border border-white/10 rounded-xl pl-16 pr-14 py-3 text-white text-xs font-black focus:border-blue-500/50 outline-none transition-all" />
<span className="absolute right-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600">Cont</span>
</div>
{/* Leverage Slider Mock */}
<div className="pt-2">
<div className="flex justify-between text-[9px] font-black uppercase text-gray-600 mb-2">
<span>{t('perpetual.panel.leverage', { defaultValue: 'Adjust Leverage' })}</span>
<span className="text-blue-500">{leverage}x</span>
</div>
<input
type="range" min="1" max="125" value={leverage}
onChange={(e) => setLeverage(parseInt(e.target.value))}
className="w-full h-1 bg-white/10 rounded-full appearance-none cursor-pointer accent-blue-500"
/>
<div className="flex justify-between text-[8px] font-black text-gray-700 mt-1 uppercase">
<span>1x</span>
<span>25x</span>
<span>50x</span>
<span>75x</span>
<span>100x</span>
<span>125x</span>
</div>
</div>
<div className="space-y-2 pt-4 border-t border-white/5">
<div className="flex justify-between text-[10px] font-black text-gray-600 uppercase tracking-widest">
<span>{t('perpetual.panel.available', { defaultValue: 'Available' })}</span>
<span className="text-white">0.00 USDT</span>
</div>
<div className="flex justify-between text-[10px] font-black text-gray-600 uppercase tracking-widest">
<span>{t('perpetual.panel.max_long', { defaultValue: 'Max Long' })}</span>
<span className="text-white">0.000 BTC</span>
</div>
</div>
<BaseButton
color="info"
label={side === 'long' ? `${t('perpetual.panel.buy', { defaultValue: 'BUY / LONG' })}` : `${t('perpetual.panel.sell', { defaultValue: 'SELL / SHORT' })}`}
className={`w-full py-4 font-black border-none text-white rounded-2xl mt-4 shadow-xl uppercase tracking-[0.2em] text-xs transition-all hover:scale-[1.02] active:scale-95 ${side === 'long' ? 'bg-emerald-500 text-black shadow-emerald-500/10' : 'bg-rose-500 text-black shadow-rose-500/10'}`}
/>
</div>
</div>
{/* Order Book Minimal */}
<div className="flex-1 p-6 overflow-hidden flex flex-col">
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-gray-500 mb-4">{t('perpetual.orderbook.title', { defaultValue: 'Market Depth' })}</h4>
<div className="flex-1 overflow-y-auto space-y-1 font-mono text-[10px] font-bold">
{[...Array(6)].map((_, i) => (
<div key={`ask-${i}`} className="flex justify-between text-rose-500 hover:bg-rose-500/10 px-2 py-0.5 rounded transition-colors">
<span>43,{(123 + (6-i)*5).toString().padStart(3, '0')}.45</span>
<span className="text-gray-500">{(Math.random() * 5).toFixed(2)}</span>
</div>
))}
<div className="py-2 px-2 text-sm font-black text-emerald-500 border-y border-white/5 my-1">
43,123.45
</div>
{[...Array(6)].map((_, i) => (
<div key={`bid-${i}`} className="flex justify-between text-emerald-500 hover:bg-emerald-500/10 px-2 py-0.5 rounded transition-colors">
<span>43,{(123 - i*5).toString().padStart(3, '0')}.45</span>
<span className="text-gray-500">{(Math.random() * 5).toFixed(2)}</span>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</>
);
};
PerpetualPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};
export default PerpetualPage;

View File

@ -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 (
<>
<Head>
<title>{getPageTitle(t('seconds.title', { defaultValue: 'Binary Options' }))}</title>
</Head>
<div className="flex flex-col h-[calc(100vh-64px)] overflow-hidden bg-[#000000] text-white">
{/* Header */}
<div className="flex items-center justify-between px-6 py-4 border-b border-white/5 bg-[#080808]">
<div className="flex items-center space-x-12">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-orange-500/10 rounded-xl flex items-center justify-center">
<BaseIcon path={icon.mdiBitcoin} size={28} className="text-orange-500" />
</div>
<div>
<div className="text-lg font-black tracking-tighter leading-none">BTC/USDT</div>
<div className="text-[10px] font-black text-blue-500 uppercase mt-1 tracking-[0.2em]">{t('seconds.header.contract', { defaultValue: 'Option Contract' })}</div>
</div>
</div>
<div className="flex items-center space-x-12">
<div>
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('seconds.header.current_price', { defaultValue: 'Current Price' })}</div>
<div className="text-emerald-500 text-xl font-black tracking-tighter animate-pulse">43,123.45</div>
</div>
<div>
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('seconds.header.yield', { defaultValue: 'Estimated Yield' })}</div>
<div className="text-emerald-500 text-lg font-black tracking-tighter">+{profit}%</div>
</div>
</div>
</div>
<div className="flex items-center space-x-6">
<div className="text-right">
<div className="text-[10px] font-black text-gray-500 uppercase tracking-widest leading-none mb-1">{t('seconds.header.balance', { defaultValue: 'Available Balance' })}</div>
<div className="text-white text-sm font-black tracking-tight">0.00 USDT</div>
</div>
<BaseButton color="info" label={t('seconds.header.deposit', { defaultValue: 'Deposit' })} small className="font-black px-6 rounded-xl" />
</div>
</div>
<div className="flex flex-1 overflow-hidden">
{/* Chart Area */}
<div className="flex-1 flex flex-col border-r border-white/5 relative">
<div id="tradingview_chart" className="flex-1"></div>
{/* Quick Stats Overlay */}
<div className="absolute top-4 left-4 flex space-x-2 z-10">
{[
{ label: '30s', yield: '75%' },
{ label: '60s', yield: '85%' },
{ label: '120s', yield: '90%' },
{ label: '300s', yield: '95%' }
].map((t) => (
<div key={t.label} className="bg-black/60 backdrop-blur-md border border-white/10 px-4 py-2 rounded-xl">
<div className="text-[10px] font-black text-gray-500 uppercase">{t.label}</div>
<div className="text-xs font-black text-emerald-500">{t.yield}</div>
</div>
))}
</div>
{/* History Tabs */}
<div className="h-64 border-t border-white/5 bg-[#080808] overflow-hidden flex flex-col">
<div className="flex border-b border-white/5">
{[
t('seconds.tabs.current', { defaultValue: 'Current Positions' }),
t('seconds.tabs.history', { defaultValue: 'Trade History' })
].map((tab, i) => (
<button key={tab} className={`px-8 py-4 text-[10px] font-black uppercase tracking-[0.2em] ${i === 0 ? 'text-blue-500 border-b-2 border-blue-500' : 'text-gray-500 hover:text-white'}`}>
{tab}
</button>
))}
</div>
<div className="flex-1 flex flex-col items-center justify-center p-8 opacity-40">
<BaseIcon path={icon.mdiHistory} size={48} className="text-gray-700 mb-2" />
<p className="text-gray-600 text-[10px] font-black uppercase tracking-widest">
{t('seconds.no_history', { defaultValue: 'No active contracts' })}
</p>
</div>
</div>
</div>
{/* Trade Panel */}
<div className="w-[360px] flex flex-col bg-[#080808] p-8">
<div className="space-y-8">
{/* Period Selection */}
<div>
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-gray-500 mb-4">{t('seconds.panel.period', { defaultValue: 'Execution Period' })}</h4>
<div className="grid grid-cols-2 gap-3">
{[30, 60, 120, 300].map(s => (
<button
key={s}
onClick={() => setPeriod(s)}
className={`py-4 rounded-2xl font-black transition-all border ${period === s ? 'bg-blue-600 border-blue-500 text-white shadow-lg shadow-blue-600/20' : 'bg-white/5 border-white/5 text-gray-500 hover:bg-white/10'}`}
>
<div className="text-lg">{s}s</div>
<div className="text-[9px] uppercase opacity-60 mt-1">{profit}% {t('seconds.panel.yield', { defaultValue: 'Yield' })}</div>
</button>
))}
</div>
</div>
{/* Amount Input */}
<div>
<h4 className="text-[10px] font-black uppercase tracking-[0.2em] text-gray-500 mb-4">{t('seconds.panel.amount', { defaultValue: 'Investment Amount' })}</h4>
<div className="relative group">
<span className="absolute left-4 top-1/2 -translate-y-1/2 text-[10px] font-black uppercase text-gray-600 group-focus-within:text-blue-500">USDT</span>
<input
type="text" value={amount} onChange={(e) => 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"
/>
</div>
<div className="grid grid-cols-4 gap-2 mt-3">
{[100, 500, 1000, 5000].map(v => (
<button key={v} onClick={() => setAmount(v.toString())} className="py-2 bg-white/5 text-[10px] font-black rounded-xl hover:bg-white/10 text-gray-500 hover:text-white transition-all">{v}</button>
))}
</div>
</div>
{/* Expected Profit */}
<div className="p-6 bg-emerald-500/5 border border-emerald-500/20 rounded-3xl">
<div className="flex justify-between items-center mb-2">
<span className="text-[10px] font-black text-gray-500 uppercase tracking-widest">{t('seconds.panel.expected_profit', { defaultValue: 'Expected Profit' })}</span>
<span className="text-emerald-500 font-black">+{profit}%</span>
</div>
<div className="text-3xl font-black text-emerald-500 tracking-tighter">
+${(parseFloat(amount || '0') * profit / 100).toFixed(2)}
</div>
</div>
{/* Trade Buttons */}
<div className="flex flex-col gap-4">
<BaseButton
label={t('seconds.panel.call', { defaultValue: 'CALL (HIGH)' })}
color="info"
className="w-full py-6 font-black bg-emerald-500 border-none text-black rounded-2xl shadow-xl shadow-emerald-500/10 hover:scale-[1.02] active:scale-95 transition-all text-lg uppercase tracking-widest"
/>
<BaseButton
label={t('seconds.panel.put', { defaultValue: 'PUT (LOW)' })}
color="danger"
className="w-full py-6 font-black bg-rose-500 border-none text-black rounded-2xl shadow-xl shadow-rose-500/10 hover:scale-[1.02] active:scale-95 transition-all text-lg uppercase tracking-widest"
/>
</div>
<p className="text-[10px] text-center text-gray-600 font-black uppercase tracking-widest leading-relaxed">
{t('seconds.panel.risk_warning', { defaultValue: 'Risk Warning: Trading involves significant risk of loss and is not suitable for all investors.' })}
</p>
</div>
</div>
</div>
</div>
</>
);
};
SecondContractPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};
export default SecondContractPage;

View File

@ -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: '',
}
};