Skip to content

Commit b15ee04

Browse files
committed
feat: swap
1 parent d9b1355 commit b15ee04

18 files changed

Lines changed: 1309 additions & 28 deletions

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"dayjs": "^1.11.20",
2121
"i18n-iso-countries": "^7.14.0",
2222
"i18next": "^26.0.3",
23+
"js-cookie": "^3.0.5",
2324
"leaflet": "^1.9.4",
2425
"react": "^19.2.4",
2526
"react-dom": "^19.2.4",
@@ -32,6 +33,7 @@
3233
"devDependencies": {
3334
"@eslint/js": "^9.39.4",
3435
"@types/geojson": "^7946.0.16",
36+
"@types/js-cookie": "^3.0.6",
3537
"@types/leaflet": "^1.9.21",
3638
"@types/node": "^24.12.0",
3739
"@types/react": "^19.2.14",

pnpm-lock.yaml

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/assets/styles.css

Lines changed: 291 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ body {
258258
cursor: pointer;
259259
}
260260

261-
/* ─── Sider ──────────────────────────────────────────────────────────────── */
262261
/* ─── Sider ──────────────────────────────────────────────────────────────── */
263262

264263
.app-sider {
@@ -300,3 +299,294 @@ body {
300299
.sidebar-item {
301300
color: transparent !important;
302301
}
302+
303+
.swap-page {
304+
display: flex;
305+
flex-direction: column;
306+
align-items: center;
307+
gap: 20px;
308+
}
309+
310+
.swap-card {
311+
background: var(--ant-color-bg-container);
312+
border-radius: 14px;
313+
padding: 32px 36px;
314+
width: 100%;
315+
max-width: 780px;
316+
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.08);
317+
border: 1px solid var(--ant-color-border-secondary);
318+
}
319+
320+
.swap-card-labels {
321+
display: flex;
322+
align-items: center;
323+
324+
@media (max-width: 575.98px) {
325+
flex-direction: column;
326+
align-items: flex-start;
327+
328+
.swap-card-title {
329+
margin-right: 0 !important;
330+
}
331+
}
332+
}
333+
334+
.swap-card-title {
335+
display: block;
336+
margin-bottom: 24px;
337+
font-size: 16px;
338+
color: var(--ant-color-text);
339+
}
340+
341+
.swap-card-title-icon {
342+
margin-right: 8px;
343+
color: var(--ant-color-primary);
344+
}
345+
346+
.swap-row {
347+
display: flex;
348+
gap: 16px;
349+
align-items: flex-start;
350+
flex-wrap: wrap;
351+
}
352+
353+
.swap-field {
354+
flex: 1;
355+
min-width: 240px;
356+
}
357+
358+
.swap-field-label {
359+
display: block;
360+
margin-bottom: 8px;
361+
color: var(--ant-color-text-secondary);
362+
}
363+
364+
.swap-field-hint {
365+
font-size: 12px;
366+
margin-top: 4px;
367+
display: block;
368+
}
369+
370+
.swap-coin-select {
371+
width: 150px;
372+
}
373+
374+
.swap-memo-input {
375+
width: 130px;
376+
}
377+
378+
.swap-receive-input {
379+
background: var(--ant-color-bg-layout) !important;
380+
}
381+
382+
.swap-icon-col {
383+
display: flex;
384+
align-items: center;
385+
padding-top: 32px;
386+
}
387+
388+
.swap-icon-btn {
389+
border: 2px solid var(--ant-color-primary) !important;
390+
color: var(--ant-color-primary) !important;
391+
}
392+
.swap-rate-info {
393+
display: flex;
394+
gap: 16px;
395+
margin-top: 16px;
396+
flex-wrap: wrap;
397+
background: #232b36;
398+
border-radius: 8px;
399+
padding: 10px 16px;
400+
border: 1px solid #2d3748;
401+
}
402+
403+
.swap-rate-text {
404+
font-size: 13px;
405+
color: #e0e0e0;
406+
}
407+
408+
.swap-divider {
409+
margin: 20px 0;
410+
border-color: #2d3748;
411+
}
412+
413+
.swap-actions {
414+
display: flex;
415+
justify-content: flex-end;
416+
gap: 16px;
417+
margin-top: 24px;
418+
}
419+
420+
.swap-deposit-alert {
421+
margin-bottom: 20px;
422+
}
423+
424+
.swap-confirm {
425+
background: #030303;
426+
}
427+
428+
.swap-deposit-label {
429+
display: block;
430+
margin-bottom: 10px;
431+
font-size: 15px;
432+
color: #f3f4f6;
433+
}
434+
435+
.swap-deposit-input {
436+
font-family: monospace;
437+
}
438+
439+
.swap-help-bubble {
440+
position: fixed;
441+
bottom: 24px;
442+
right: 24px;
443+
width: 48px;
444+
height: 48px;
445+
border-radius: 50%;
446+
background: #030303;
447+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
448+
display: flex;
449+
align-items: center;
450+
justify-content: center;
451+
cursor: pointer;
452+
border: 1px solid #2d3748;
453+
z-index: 1;
454+
455+
&:hover {
456+
border-color: #fff;
457+
transition: border-color 0.2s ease;
458+
}
459+
}
460+
461+
.swap-help-icon {
462+
font-size: 20px;
463+
color: #e0e0e0;
464+
}
465+
466+
.faq-page {
467+
display: flex;
468+
flex-direction: column;
469+
align-items: center;
470+
width: 100%;
471+
}
472+
473+
.faq-title {
474+
font-weight: 600;
475+
margin: 0 0 8px;
476+
color: #f3f4f6;
477+
}
478+
479+
.faq-subtitle {
480+
margin-bottom: 32px;
481+
font-size: 18px;
482+
text-align: center;
483+
}
484+
485+
.faq-tags {
486+
margin-bottom: 36px;
487+
justify-content: center;
488+
}
489+
490+
.faq-tag {
491+
cursor: pointer;
492+
font-size: 16px;
493+
padding: 4px 16px;
494+
border-radius: 20px;
495+
}
496+
497+
.faq-search-icon {
498+
color: #6b7280;
499+
}
500+
501+
.faq-search {
502+
max-width: 500px;
503+
width: 100%;
504+
margin-bottom: 28px;
505+
border-radius: 8px;
506+
}
507+
508+
.faq-list {
509+
width: 100%;
510+
max-width: 780px;
511+
}
512+
513+
.faq-empty {
514+
text-align: center;
515+
padding: 40px 0;
516+
}
517+
518+
.faq-empty-icon {
519+
font-size: 40px;
520+
color: #6b7280;
521+
margin-bottom: 16px;
522+
display: block;
523+
}
524+
525+
.faq-category {
526+
margin-bottom: 20px;
527+
}
528+
529+
.faq-category-header {
530+
margin-bottom: 10px;
531+
}
532+
533+
.faq-category-label {
534+
font-size: 22px;
535+
}
536+
537+
.faq-collapse {
538+
border-radius: 16px;
539+
overflow: hidden;
540+
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.3);
541+
border: 1px solid #2d3748;
542+
position: relative;
543+
}
544+
545+
.faq-question {
546+
font-size: 18px;
547+
cursor: pointer;
548+
}
549+
550+
.faq-answer {
551+
line-height: 1.8;
552+
font-size: 16px;
553+
}
554+
555+
.faq-cta {
556+
margin-top: 40px;
557+
border-radius: 16px;
558+
padding: 24px 36px;
559+
width: 100%;
560+
max-width: 780px;
561+
text-align: center;
562+
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.3);
563+
border: 1px solid #2d3748;
564+
display: flex;
565+
flex-direction: column;
566+
gap: 4px;
567+
position: relative;
568+
margin-bottom: 24px;
569+
}
570+
571+
.faq-cta-title {
572+
font-size: 20px;
573+
}
574+
575+
.faq-cta-subtitle {
576+
font-size: 16px;
577+
}
578+
579+
.faq-cta-links {
580+
margin-top: 16px;
581+
justify-content: center;
582+
}
583+
584+
.faq-cta-link {
585+
font-size: 18px;
586+
color: #ba2a45;
587+
588+
&:hover {
589+
opacity: 0.8;
590+
color: #ba2a45;
591+
}
592+
}

src/layout/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
SwapOutlined,
66
ClusterOutlined,
77
MenuOutlined,
8-
NodeIndexOutlined
8+
NodeIndexOutlined,
9+
QuestionCircleOutlined
910
} from '@ant-design/icons';
1011
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
1112
import { useEffect, useState } from 'react';
@@ -25,7 +26,8 @@ const NAV_ITEMS = [
2526
icon: <ClusterOutlined style={{ fontSize: 22 }} />,
2627
label: 'Masternodes'
2728
},
28-
{ key: '/swap', icon: <SwapOutlined style={{ fontSize: 22 }} />, label: 'Swap' }
29+
{ key: '/swap', icon: <SwapOutlined style={{ fontSize: 22 }} />, label: 'Swap' },
30+
{ key: '/faq', icon: <QuestionCircleOutlined style={{ fontSize: 22 }} />, label: 'FAQ' }
2931
];
3032

3133
export default function AppLayout() {

0 commit comments

Comments
 (0)