updated cards,borrow page (#102)
This commit is contained in:
parent
b5c097d661
commit
29ce98f4d7
@ -1,88 +0,0 @@
|
|||||||
<svg width="1440" height="4655" viewBox="0 0 1440 4655" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0)">
|
|
||||||
<rect width="1440" height="4655" fill="white"/>
|
|
||||||
<rect x="-95" width="1630" height="4655" fill="white"/>
|
|
||||||
<rect x="-95" width="1630" height="4655" fill="url(#paint0_linear)" fillOpacity="0.9"/>
|
|
||||||
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter0_f)">
|
|
||||||
<path d="M-95 81H-41.5427C-21.4963 98.2997 20.9354 132.416 30.2904 130.485C39.6454 128.554 57.9471 143.762 65.9286 151.607C85.2326 168.303 124.843 201.454 128.852 200.488C130.084 200.192 133.976 200.223 139.641 200.269C157.018 200.41 191.081 200.687 216.277 192.04C249.688 180.574 266.95 185.402 278.087 192.04C289.224 198.678 349.92 229.455 360.5 227.041C364.049 226.232 374.49 226.916 387.221 227.75C412.442 229.403 446.649 231.644 454.05 224.024C465.187 212.558 658.97 204.713 677.346 214.368C692.047 222.093 711.462 222.214 720 222.214C728.538 222.214 747.953 222.093 762.654 214.368C781.03 204.713 974.812 212.558 985.949 224.024C993.351 231.644 1027.56 229.403 1052.78 227.75C1065.51 226.916 1075.95 226.232 1079.5 227.041C1090.08 229.455 1150.78 198.678 1161.91 192.04C1173.05 185.402 1190.31 180.574 1223.72 192.04C1248.92 200.687 1282.98 200.41 1300.36 200.269C1306.02 200.223 1309.92 200.192 1311.15 200.488C1315.16 201.454 1354.77 168.303 1374.07 151.607C1382.05 143.762 1400.35 128.554 1409.71 130.485C1419.06 132.416 1461.5 98.2997 1481.54 81H1535V5699H-95V81Z" fill="url(#paint1_linear)"/>
|
|
||||||
</g>
|
|
||||||
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter1_b)">
|
|
||||||
<path d="M-94.4432 513.757L-95 340.635C-79.1818 340.214 -58.0175 340.376 -39.8412 340.516C-31.7833 340.577 -24.3126 340.635 -18.1552 340.635C0.777557 340.635 41.9842 351.569 77.0655 371.007C80.0141 371.713 82.7676 372.389 85.3812 373.03C103.005 377.355 114.269 380.119 136.091 380.119L288.11 383.156C290.709 382.751 297.02 380.604 301.475 375.259C305.929 369.913 317.066 360.882 322.078 357.035C325.605 354.808 335.665 350.353 347.693 350.353C357.225 350.353 369.218 351.086 377.998 351.622C383.067 351.932 387.065 352.176 388.899 352.176C393.911 352.176 406.162 349.138 410.616 344.279C414.18 340.391 449.967 297.303 467.415 276.245C473.54 269.36 489.8 256.928 505.837 262.274C525.884 268.955 581.011 268.955 589.921 262.274C598.831 255.592 619.434 244.051 639.48 247.696C641.661 248.092 644.286 248.57 647.239 249.108C671.427 253.515 717.519 261.913 720 261.913C722.481 261.913 768.573 253.515 792.761 249.108C795.714 248.57 798.339 248.092 800.52 247.696C820.566 244.051 841.169 255.592 850.079 262.274C858.989 268.955 914.116 268.955 934.163 262.274C950.2 256.928 966.46 269.36 972.585 276.245C990.033 297.303 1025.82 340.391 1029.38 344.279C1033.84 349.138 1046.09 352.176 1051.1 352.176C1052.93 352.176 1056.93 351.932 1062 351.622C1070.78 351.086 1082.78 350.353 1092.31 350.353C1104.34 350.353 1114.4 354.808 1117.92 357.035C1122.93 360.882 1134.07 369.913 1138.53 375.259C1142.98 380.604 1149.29 382.751 1151.89 383.156L1303.91 380.119C1325.73 380.119 1336.99 377.355 1354.62 373.03C1357.23 372.389 1359.99 371.713 1362.93 371.007C1398.02 351.569 1439.22 340.635 1458.16 340.635C1464.31 340.635 1471.78 340.577 1479.84 340.516C1498.02 340.376 1519.18 340.214 1535 340.635L1534.44 513.757L1535 5735H-95L-94.4432 513.757Z" fill="url(#paint2_linear)"/>
|
|
||||||
</g>
|
|
||||||
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter2_b)">
|
|
||||||
<path d="M-94.4432 564.916L-95 459.824C-83.4012 458.344 -70.3203 456.725 -56.3558 454.996C23.3155 445.133 131.749 431.709 157.808 420.338C174.83 417.587 251.452 426.321 319.591 434.089C371.82 440.042 419.065 445.428 430.663 444.637C438.9 444.075 458.907 436.012 485.925 425.125C546.58 400.681 642.565 362 720 362C797.435 362 893.42 400.681 954.075 425.125C981.093 436.012 1001.1 444.075 1009.34 444.637C1020.94 445.428 1068.18 440.042 1120.41 434.089C1188.55 426.321 1265.17 417.587 1282.19 420.338C1308.25 431.709 1416.68 445.133 1496.36 454.996C1510.32 456.725 1523.4 458.344 1535 459.824L1534.44 564.916L1535 5694H-95L-94.4432 564.916Z" fill="url(#paint3_linear)"/>
|
|
||||||
</g>
|
|
||||||
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter3_f)">
|
|
||||||
<path d="M-95 474.713C-74.9535 467.22 -31.8536 452.843 -22.0531 455.273C-9.80252 458.311 30.2904 476.535 41.9842 492.33C53.678 508.124 75.3046 507.008 77.0655 505.087C78.736 503.265 93.7709 492.127 101.567 486.862C106.207 484.432 118.384 481.03 129.966 486.862C141.548 492.694 209.409 526.552 241.892 542.751C246.161 545.181 255.034 550.041 256.37 550.041C256.615 550.041 257.181 550.093 257.983 550.167C262.657 550.596 275.317 551.76 278.644 547.611C281.762 543.723 299.247 530.197 307.6 523.919C313.725 519.869 328.537 511.769 338.783 511.769C349.029 511.769 421.382 515.819 456.278 517.844C476.51 517.439 518.088 516.508 522.542 516.022C525.854 515.66 557.031 517.663 583.224 519.345C601.072 520.491 616.606 521.489 619.434 521.489C622.857 521.489 633.093 514.341 646.164 505.215C669.243 489.1 701.158 466.815 720 466.815C738.842 466.815 770.757 489.1 793.836 505.215C806.907 514.341 817.143 521.489 820.566 521.489C823.394 521.489 838.928 520.491 856.776 519.345C882.969 517.663 914.146 515.66 917.458 516.022C921.912 516.508 963.49 517.439 983.722 517.844C1018.62 515.819 1090.97 511.769 1101.22 511.769C1111.46 511.769 1126.27 519.869 1132.4 523.919C1140.75 530.197 1158.24 543.723 1161.36 547.611C1164.68 551.76 1177.34 550.596 1182.02 550.167C1182.82 550.093 1183.39 550.041 1183.63 550.041C1184.97 550.041 1193.84 545.181 1198.11 542.751C1230.59 526.552 1298.45 492.694 1310.03 486.862C1321.62 481.03 1333.79 484.432 1338.43 486.862C1346.23 492.127 1361.26 503.265 1362.93 505.087C1364.7 507.008 1386.32 508.124 1398.02 492.33C1409.71 476.535 1449.8 458.311 1462.05 455.273C1471.85 452.843 1514.95 467.22 1535 474.713V5633H-95V474.713Z" fill="url(#paint4_linear)"/>
|
|
||||||
</g>
|
|
||||||
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter4_f)">
|
|
||||||
<path d="M-48.7082 749.921C-44.5423 750.554 -40.9302 751.102 -38.2017 751.102C-34.8768 751.102 -32.6091 748.668 -30.2117 746.094C-27.3895 743.063 -24.3874 739.84 -19.2689 740.168C-11.6958 740.654 56.2766 740.371 89.3161 740.168L101.01 742.597L154.467 778.437L160.592 789.371L195.117 792.408L230.755 805.165C243.748 808.607 270.959 815.248 275.86 814.276C278.968 813.66 288.245 806.784 297.502 799.923C306.484 793.266 315.446 786.624 318.737 785.726C325.419 783.904 346.022 774.185 349.363 771.148C349.667 770.872 350.104 770.455 350.656 769.929C356.186 764.659 373.307 748.342 384.445 751.102C389.517 752.36 394.495 755.18 399.337 757.923C406.189 761.805 412.77 765.533 418.969 764.466C426.043 763.247 448.304 744.104 463.112 731.37C470.451 725.06 475.959 720.323 476.881 720.122C479.109 719.636 515.304 681.043 533.123 661.807C539.062 655.53 556.733 646.986 575.443 655.733C594.153 664.48 621.476 664.844 633.355 664.844L701.29 670.918L720 670.86L738.71 670.918L806.645 664.844C818.524 664.844 845.847 664.48 864.557 655.733C883.267 646.986 900.938 655.53 906.877 661.807C924.696 681.043 960.891 719.636 963.119 720.122C964.041 720.323 969.549 725.06 976.888 731.37C991.696 744.104 1013.96 763.247 1021.03 764.466C1027.23 765.533 1033.81 761.805 1040.66 757.923C1045.51 755.18 1050.48 752.36 1055.56 751.102C1066.69 748.342 1083.81 764.659 1089.34 769.929C1089.9 770.455 1090.33 770.872 1090.64 771.148C1093.98 774.185 1114.58 783.904 1121.26 785.726C1124.55 786.624 1133.52 793.266 1142.5 799.923C1151.75 806.784 1161.03 813.66 1164.14 814.276C1169.04 815.248 1196.25 808.607 1209.24 805.165L1244.88 792.408L1279.41 789.371L1285.53 778.437L1338.99 742.597L1350.68 740.168C1383.72 740.371 1451.7 740.654 1459.27 740.168C1464.39 739.84 1467.39 743.063 1470.21 746.094C1472.61 748.668 1474.88 751.102 1478.2 751.102C1480.93 751.102 1484.54 750.554 1488.71 749.921C1502.07 747.89 1521.13 744.994 1535 756.571V5699H-95V756.571C-81.1327 744.994 -62.0716 747.89 -48.7082 749.921Z" fill="url(#paint5_linear)" fillOpacity="0.55"/>
|
|
||||||
</g>
|
|
||||||
<ellipse opacity="0.2" cx="720.5" cy="532.5" rx="1003.5" ry="1123.5" transform="rotate(-90 720.5 532.5)" fill="url(#paint6_radial)"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<filter id="filter0_f" x="-102" y="74" width="1644" height="5632" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
||||||
<feGaussianBlur stdDeviation="3.5" result="effect1_foregroundBlur"/>
|
|
||||||
</filter>
|
|
||||||
<filter id="filter1_b" x="-103" y="239" width="1646" height="5504" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feGaussianBlur in="BackgroundImage" stdDeviation="4"/>
|
|
||||||
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
<filter id="filter2_b" x="-98" y="359" width="1636" height="5338" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feGaussianBlur in="BackgroundImage" stdDeviation="1.5"/>
|
|
||||||
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
<filter id="filter3_f" x="-98.5" y="451.5" width="1637" height="5185" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
||||||
<feGaussianBlur stdDeviation="1.75" result="effect1_foregroundBlur"/>
|
|
||||||
</filter>
|
|
||||||
<filter id="filter4_f" x="-97" y="650" width="1634" height="5051" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
||||||
<feGaussianBlur stdDeviation="1" result="effect1_foregroundBlur"/>
|
|
||||||
</filter>
|
|
||||||
<linearGradient id="paint0_linear" x1="709.247" y1="-90.5139" x2="709.247" y2="4655" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#EB9E49"/>
|
|
||||||
<stop offset="0.078125" stop-color="#CD4E59"/>
|
|
||||||
<stop offset="0.151042" stop-color="#6E3D6E"/>
|
|
||||||
<stop offset="0.437386" stop-color="#582B3F"/>
|
|
||||||
<stop offset="0.750045" stop-color="#46172C"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear" x1="718.886" y1="234.273" x2="719.05" y2="554.095" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#202020"/>
|
|
||||||
<stop offset="1" stop-color="#807575"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint2_linear" x1="720" y1="331.517" x2="720.166" y2="784.035" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#610409" stop-opacity="0.35"/>
|
|
||||||
<stop offset="0.40625" stop-color="#524C4C"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint3_linear" x1="720.557" y1="362" x2="720.557" y2="816.963" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#5A0013" stop-opacity="0.54"/>
|
|
||||||
<stop offset="1" stop-color="#AEAEAE"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint4_linear" x1="720.556" y1="455" x2="720.556" y2="5633" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#2B0109" stop-opacity="0.37"/>
|
|
||||||
<stop offset="0.25" stop-color="#610D32"/>
|
|
||||||
<stop offset="1" stop-color="#610D32"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint5_linear" x1="720" y1="621.113" x2="720" y2="5830.2" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#545454" stop-opacity="0.08"/>
|
|
||||||
<stop offset="0.0001" stop-color="#390013"/>
|
|
||||||
<stop offset="1" stop-color="#582B3F"/>
|
|
||||||
</linearGradient>
|
|
||||||
<radialGradient id="paint6_radial" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(720.5 636.394) rotate(90) scale(1019.61 910.703)">
|
|
||||||
<stop stop-color="#C85658"/>
|
|
||||||
<stop offset="1" stop-color="#FF0707" stop-opacity="0"/>
|
|
||||||
</radialGradient>
|
|
||||||
<clipPath id="clip0">
|
|
||||||
<rect width="1440" height="4655" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 12 KiB |
1
public/images/sort-asc.svg
Normal file
1
public/images/sort-asc.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M12 7.64031L15.5746 10.5L8.42539 10.5L12 7.64031Z" fill="#FFFFFF" stroke="#FFFFFF" stroke-linejoin="round"></path><path d="M11.6877 16.7501L8.11304 13.8904C7.74397 13.5952 7.95275 13 8.42539 13H15.5746C16.0472 13 16.256 13.5952 15.887 13.8904L12.3123 16.7501C12.1297 16.8962 11.8703 16.8962 11.6877 16.7501Z" fill="#FFFFFF" fill-opacity="0.2"></path></svg>
|
After Width: | Height: | Size: 460 B |
1
public/images/sort-desc.svg
Normal file
1
public/images/sort-desc.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M12.3123 7.24988L15.887 10.1096C16.256 10.4048 16.0472 11 15.5746 11L8.42539 11C7.95275 11 7.74397 10.4048 8.11304 10.1096L11.6877 7.24988C11.8703 7.10379 12.1297 7.10379 12.3123 7.24988Z" fill="white" fill-opacity="0.2"></path><path d="M12 16.3597L8.42539 13.5L15.5746 13.5L12 16.3597Z" fill="#FFFFFF" stroke="#FFFFFF" stroke-linejoin="round"></path></svg>
|
After Width: | Height: | Size: 461 B |
1
public/images/sort-none.svg
Normal file
1
public/images/sort-none.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M12.3123 7.24988L15.887 10.1096C16.256 10.4048 16.0472 11 15.5746 11L8.42539 11C7.95275 11 7.74397 10.4048 8.11304 10.1096L11.6877 7.24988C11.8703 7.10379 12.1297 7.10379 12.3123 7.24988Z" fill="#FFFFFF" fill-opacity="0.2"></path><path d="M11.6877 16.7501L8.11304 13.8904C7.74397 13.5952 7.95275 13 8.42539 13H15.5746C16.0472 13 16.256 13.5952 15.887 13.8904L12.3123 16.7501C12.1297 16.8962 11.8703 16.8962 11.6877 16.7501Z" fill="#FFFFFF" fill-opacity="0.2"></path></svg>
|
After Width: | Height: | Size: 576 B |
@ -1,3 +1,5 @@
|
|||||||
export default function Loading() {
|
import Loading from 'components/Loading'
|
||||||
return '...isLoading'
|
|
||||||
|
export default function page() {
|
||||||
|
return <Loading />
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,51 @@
|
|||||||
import { BorrowTable } from 'components/BorrowTable'
|
import { BorrowTable } from 'components/Borrow/BorrowTable'
|
||||||
import { AccountDebtTable } from 'components/AccountDebtTable'
|
|
||||||
import { Card } from 'components/Card'
|
import { Card } from 'components/Card'
|
||||||
import Loading from 'components/Loading'
|
import Loading from 'components/Loading'
|
||||||
import { Text } from 'components/Text'
|
import { Text } from 'components/Text'
|
||||||
import { Suspense } from 'react'
|
import { Suspense } from 'react'
|
||||||
|
import { getAccountDebts, getBorrowData } from 'utils/api'
|
||||||
|
import { getMarketAssets } from 'utils/assets'
|
||||||
|
|
||||||
|
export default async function page({ params }: { params: PageParams }) {
|
||||||
|
const debtData = await getAccountDebts(params.account)
|
||||||
|
const borrowData = await getBorrowData()
|
||||||
|
|
||||||
|
const marketAssets = getMarketAssets()
|
||||||
|
|
||||||
|
const { available, active } = marketAssets.reduce(
|
||||||
|
(prev: { available: BorrowAsset[]; active: BorrowAssetActive[] }, curr) => {
|
||||||
|
const borrow = borrowData.find((borrow) => borrow.denom === curr.denom)
|
||||||
|
if (borrow) {
|
||||||
|
const debt = debtData.find((debt) => debt.denom === curr.denom)
|
||||||
|
if (debt) {
|
||||||
|
prev.active.push({
|
||||||
|
...borrow,
|
||||||
|
debt: {
|
||||||
|
amount: '100000',
|
||||||
|
value: '12389478321',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
prev.available.push(borrow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prev
|
||||||
|
},
|
||||||
|
{ available: [], active: [] },
|
||||||
|
)
|
||||||
|
|
||||||
export default function page({ params }: { params: PageParams }) {
|
|
||||||
return (
|
return (
|
||||||
<div className='flex w-full flex-col'>
|
<div className='flex w-full flex-col'>
|
||||||
<Card className='mb-4'>
|
{active.length > 0 && (
|
||||||
<Text size='lg' uppercase>
|
<Card title='Borrowings'>
|
||||||
Debt data
|
<BorrowTable data={active} />
|
||||||
</Text>
|
|
||||||
<Suspense fallback={<Loading className='h-full w-full' />}>
|
|
||||||
{/* @ts-expect-error Server Component */}
|
|
||||||
<AccountDebtTable account={params.account} />
|
|
||||||
</Suspense>
|
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
)}
|
||||||
<Text size='lg' uppercase>
|
{available.length > 0 && (
|
||||||
Borrow data
|
<Card title='Available to borrow'>
|
||||||
</Text>
|
<BorrowTable data={available} />
|
||||||
<Suspense fallback={<Loading className='h-full w-full' />}>
|
|
||||||
{/* @ts-expect-error Server Component */}
|
|
||||||
<BorrowTable />
|
|
||||||
</Suspense>
|
|
||||||
</Card>
|
</Card>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
import { Card } from 'components/Card'
|
import { Card } from 'components/Card'
|
||||||
import { Text } from 'components/Text'
|
|
||||||
|
|
||||||
export default function page() {
|
export default function page() {
|
||||||
return (
|
return (
|
||||||
<div className='flex w-full'>
|
<div className='flex w-full'>
|
||||||
<Card>
|
<Card title='Council'>
|
||||||
<Text size='lg' uppercase>
|
<></>
|
||||||
Council Placeholder
|
|
||||||
</Text>
|
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -4,18 +4,9 @@ import { Text } from 'components/Text'
|
|||||||
export default function page() {
|
export default function page() {
|
||||||
return (
|
return (
|
||||||
<div className='flex w-full gap-4'>
|
<div className='flex w-full gap-4'>
|
||||||
<Card>
|
<Card title='Yield'>
|
||||||
<Text size='lg' uppercase>
|
<></>
|
||||||
Yield Module
|
|
||||||
</Text>
|
|
||||||
</Card>
|
</Card>
|
||||||
<div className='w-[450px]'>
|
|
||||||
<Card>
|
|
||||||
<Text size='lg' uppercase>
|
|
||||||
Placeholder
|
|
||||||
</Text>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,20 @@
|
|||||||
import { Card } from 'components/Card'
|
import { Card } from 'components/Card'
|
||||||
import { Text } from 'components/Text'
|
|
||||||
|
|
||||||
export default function page() {
|
export default function page() {
|
||||||
return (
|
return (
|
||||||
<div className='flex w-full flex-wrap'>
|
<div className='flex w-full flex-wrap'>
|
||||||
<div className='mb-4 flex flex-grow gap-4'>
|
<div className='mb-4 flex flex-grow gap-4'>
|
||||||
<Card className='flex-1'>
|
<Card title='TradingView graph' className='flex-1'>
|
||||||
<Text size='lg' uppercase>
|
<></>
|
||||||
Tradingview Graph
|
|
||||||
</Text>
|
|
||||||
</Card>
|
</Card>
|
||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
<Card>{/* <TradeActionModule /> */}</Card>
|
<Card title='Orderbook module'>
|
||||||
<Card>
|
<></>
|
||||||
<Text size='lg' uppercase>
|
|
||||||
Orderbook module (optional)
|
|
||||||
</Text>
|
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Card>
|
<Card title='Order history'>
|
||||||
<Text size='lg' uppercase>
|
<></>
|
||||||
Order history
|
|
||||||
</Text>
|
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -15,7 +15,7 @@ export default async function RootLayout({
|
|||||||
<div className='relative hidden bg-header lg:block'>
|
<div className='relative hidden bg-header lg:block'>
|
||||||
<AccountNavigation creditAccounts={creditAccounts} />
|
<AccountNavigation creditAccounts={creditAccounts} />
|
||||||
</div>
|
</div>
|
||||||
{children}
|
<main className='p-4'>{children}</main>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
const filter = {
|
|
||||||
day: 'brightness-100 hue-rotate-0',
|
|
||||||
night: '-hue-rotate-82 brightness-30',
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Background() {
|
export default function Background() {
|
||||||
const { status } = useWalletManager()
|
|
||||||
|
|
||||||
const backgroundClasses = classNames(
|
const backgroundClasses = classNames(
|
||||||
status === WalletConnectionStatus.Connected ? filter.day : filter.night,
|
'top-0 left-0 absolute block h-full w-full flex-col bg-body bg-desktop bg-top bg-no-repeat filter bg-[#06040C]',
|
||||||
'top-0 left-0 absolute block h-full w-full flex-col bg-body bg-mars bg-desktop bg-top bg-no-repeat filter',
|
|
||||||
true && 'transition-background duration-3000 ease-linear',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return <div className={backgroundClasses} />
|
return <div className={backgroundClasses} />
|
||||||
|
41
src/components/Borrow/AssetExpanded.tsx
Normal file
41
src/components/Borrow/AssetExpanded.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { getMarketAssets } from 'utils/assets'
|
||||||
|
import { Row } from '@tanstack/react-table'
|
||||||
|
import { Button } from 'components/Button'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
|
||||||
|
type AssetRowProps = {
|
||||||
|
row: Row<BorrowAsset>
|
||||||
|
onBorrowClick: () => void
|
||||||
|
onRepayClick: () => void
|
||||||
|
resetExpanded: (defaultState?: boolean | undefined) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AssetExpanded(props: AssetRowProps) {
|
||||||
|
const router = useRouter()
|
||||||
|
const marketAssets = getMarketAssets()
|
||||||
|
const asset = marketAssets.find((asset) => asset.denom === props.row.original.denom)
|
||||||
|
|
||||||
|
if (!asset) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr
|
||||||
|
key={props.row.id}
|
||||||
|
className='cursor-pointer'
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
const isExpanded = props.row.getIsExpanded()
|
||||||
|
props.resetExpanded()
|
||||||
|
!isExpanded && props.row.toggleExpanded()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<td colSpan={4}>
|
||||||
|
<div className='flex justify-end p-4'>
|
||||||
|
<Button color='secondary' text='CLick me' onClick={() => router.refresh()} />
|
||||||
|
<Button color='primary' text='CLick me' />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
@ -1,85 +1,37 @@
|
|||||||
import Image from 'next/image'
|
import React from 'react'
|
||||||
import React, { useState } from 'react'
|
|
||||||
|
|
||||||
import { ChevronDown, ChevronUp } from 'components/Icons'
|
import { getMarketAssets } from 'utils/assets'
|
||||||
import { formatCurrency } from 'utils/formatters'
|
import { flexRender, Row } from '@tanstack/react-table'
|
||||||
import { Button } from 'components/Button'
|
|
||||||
|
|
||||||
type AssetRowProps = {
|
type AssetRowProps = {
|
||||||
data: {
|
row: Row<BorrowAsset>
|
||||||
denom: string
|
resetExpanded: (defaultState?: boolean | undefined) => void
|
||||||
symbol: string
|
|
||||||
logo: string
|
|
||||||
name: string
|
|
||||||
borrowed: {
|
|
||||||
amount: number
|
|
||||||
value: number
|
|
||||||
} | null
|
|
||||||
borrowRate: number
|
|
||||||
marketLiquidity: number
|
|
||||||
}
|
|
||||||
onBorrowClick: () => void
|
|
||||||
onRepayClick: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AssetRow = ({ data, onBorrowClick, onRepayClick }: AssetRowProps) => {
|
export const AssetRow = (props: AssetRowProps) => {
|
||||||
const [isExpanded, setIsExpanded] = useState(false)
|
const marketAssets = getMarketAssets()
|
||||||
|
const asset = marketAssets.find((asset) => asset.denom === props.row.original.denom)
|
||||||
|
|
||||||
|
if (!asset) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<tr
|
||||||
className='cursor-pointer rounded-md px-4 py-2 hover:bg-black/30'
|
key={props.row.id}
|
||||||
onClick={() => setIsExpanded((current) => !current)}
|
className='cursor-pointer'
|
||||||
>
|
onClick={(e) => {
|
||||||
<div className='flex'>
|
e.preventDefault()
|
||||||
<div className='flex flex-1 items-center'>
|
const isExpanded = props.row.getIsExpanded()
|
||||||
<Image src={data.logo} alt='token' width={32} height={32} />
|
props.resetExpanded()
|
||||||
<div className='pl-2'>
|
!isExpanded && props.row.toggleExpanded()
|
||||||
<div>{data.symbol}</div>
|
|
||||||
<div className='text-xs'>{data.name}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='flex flex-1 items-center text-xs'>
|
|
||||||
{data.borrowRate ? `${(data.borrowRate * 100).toFixed(2)}%` : '-'}
|
|
||||||
</div>
|
|
||||||
<div className='flex flex-1 items-center text-xs'>
|
|
||||||
{data.borrowed ? (
|
|
||||||
<div>
|
|
||||||
<div className='font-bold'>{data.borrowed.amount}</div>
|
|
||||||
<div>{formatCurrency(data.borrowed.value)}</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
'-'
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className='flex flex-1 items-center text-xs'>{data.marketLiquidity}</div>
|
|
||||||
<div className='flex w-[50px] items-center justify-end'>
|
|
||||||
<div className='w-5'>{isExpanded ? <ChevronUp /> : <ChevronDown />}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{isExpanded && (
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div>Additional Stuff Placeholder</div>
|
|
||||||
<div className='flex gap-2'>
|
|
||||||
<Button
|
|
||||||
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
onBorrowClick()
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Borrow
|
{props.row.getVisibleCells().map((cell, index) => {
|
||||||
</Button>
|
return (
|
||||||
<Button
|
<td key={cell.id} className={'p-4 text-right'}>
|
||||||
disabled={!data.borrowed}
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||||
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
</td>
|
||||||
e.stopPropagation()
|
)
|
||||||
onRepayClick()
|
})}
|
||||||
}}
|
</tr>
|
||||||
>
|
|
||||||
Repay
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
flexRender,
|
flexRender,
|
||||||
@ -11,76 +13,53 @@ import React from 'react'
|
|||||||
|
|
||||||
import { AssetRow } from 'components/Borrow/AssetRow'
|
import { AssetRow } from 'components/Borrow/AssetRow'
|
||||||
import { ChevronDown, ChevronUp } from 'components/Icons'
|
import { ChevronDown, ChevronUp } from 'components/Icons'
|
||||||
import { formatCurrency } from 'utils/formatters'
|
import { getMarketAssets } from 'utils/assets'
|
||||||
|
import classNames from 'classnames'
|
||||||
interface Market {
|
import AssetExpanded from './AssetExpanded'
|
||||||
denom: string
|
|
||||||
symbol: string
|
|
||||||
logo: string
|
|
||||||
name: string
|
|
||||||
borrowed: {
|
|
||||||
amount: number
|
|
||||||
value: number
|
|
||||||
} | null
|
|
||||||
borrowRate: number
|
|
||||||
marketLiquidity: number
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: Market[]
|
data: BorrowAsset[] | BorrowAssetActive[]
|
||||||
onBorrowClick: (denom: string) => void
|
|
||||||
onRepayClick: (denom: string) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BorrowTable = ({ data, onBorrowClick, onRepayClick }: Props) => {
|
export const BorrowTable = (props: Props) => {
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
const [sorting, setSorting] = React.useState<SortingState>([])
|
||||||
|
const marketAssets = getMarketAssets()
|
||||||
|
|
||||||
const columns = React.useMemo<ColumnDef<Market>[]>(
|
const columns = React.useMemo<ColumnDef<BorrowAsset>[]>(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
header: 'Asset',
|
header: 'Asset',
|
||||||
id: 'symbol',
|
id: 'symbol',
|
||||||
accessorFn: (row) => (
|
cell: ({ row }) => {
|
||||||
|
const asset = marketAssets.find((asset) => asset.denom === row.original.denom)
|
||||||
|
|
||||||
|
if (!asset) return null
|
||||||
|
|
||||||
|
return (
|
||||||
<div className='flex flex-1 items-center'>
|
<div className='flex flex-1 items-center'>
|
||||||
<Image src={row.logo} alt='token' width={32} height={32} />
|
<Image src={asset.logo} alt='token' width={32} height={32} />
|
||||||
<div className='pl-2'>
|
<div className='pl-2'>
|
||||||
<div>{row.symbol}</div>
|
<div>{asset.symbol}</div>
|
||||||
<div className='text-xs'>{row.name}</div>
|
<div className='text-xs'>{asset.name}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
),
|
)
|
||||||
cell: (info) => info.getValue(),
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'borrowRate',
|
accessorKey: 'borrowRate',
|
||||||
header: 'Borrow Rate',
|
header: 'Borrow Rate',
|
||||||
accessorFn: (row) => (
|
cell: ({ row }) => <div>{(Number(row.original.borrowRate) * 100).toFixed(2)}%</div>,
|
||||||
<div className='flex flex-1 items-center text-xs'>
|
|
||||||
{row.borrowRate ? `${(row.borrowRate * 100).toFixed(2)}%` : '-'}
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
cell: (info) => info.getValue(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'age',
|
accessorKey: 'liquidity',
|
||||||
header: 'Borrowed',
|
|
||||||
accessorFn: (row) => (
|
|
||||||
<div className='flex flex-1 items-center text-xs'>
|
|
||||||
{row.borrowed ? (
|
|
||||||
<div>
|
|
||||||
<div className='font-bold'>{row.borrowed.amount}</div>
|
|
||||||
<div>{formatCurrency(row.borrowed.value)}</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
'-'
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
cell: (info) => info.getValue(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: 'marketLiquidity',
|
|
||||||
header: 'Liquidity Available',
|
header: 'Liquidity Available',
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className='items-right flex flex-col'>
|
||||||
|
<div className=''>{row.original.liquidity.amount}</div>
|
||||||
|
<div className='text-xs opacity-60'>${row.original.liquidity.value}</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'status',
|
accessorKey: 'status',
|
||||||
@ -98,7 +77,7 @@ export const BorrowTable = ({ data, onBorrowClick, onRepayClick }: Props) => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data: props.data,
|
||||||
columns,
|
columns,
|
||||||
state: {
|
state: {
|
||||||
sorting,
|
sorting,
|
||||||
@ -110,47 +89,67 @@ export const BorrowTable = ({ data, onBorrowClick, onRepayClick }: Props) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='w-full table-fixed border-spacing-10 text-sm'>
|
<table className='w-full'>
|
||||||
|
<thead className='bg-white/5'>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
<div key={headerGroup.id} className='mb-2 flex rounded-md px-4 py-2 text-xs'>
|
<tr key={headerGroup.id}>
|
||||||
{headerGroup.headers.map((header) => {
|
{headerGroup.headers.map((header, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={header.id} className={`${header.index === 4 ? 'w-[50px]' : 'flex-1'}`}>
|
<th
|
||||||
{header.isPlaceholder ? null : (
|
key={header.id}
|
||||||
<div
|
onClick={header.column.getToggleSortingHandler()}
|
||||||
{...{
|
className={classNames(
|
||||||
className: header.column.getCanSort() ? 'cursor-pointer select-none' : '',
|
'px-4 py-2',
|
||||||
onClick: header.column.getToggleSortingHandler(),
|
header.column.getCanSort() && 'cursor-pointer',
|
||||||
}}
|
header.id === 'symbol' ? 'text-left' : 'text-right',
|
||||||
>
|
|
||||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
||||||
{{
|
|
||||||
asc: ' 🔼',
|
|
||||||
desc: ' 🔽',
|
|
||||||
}[header.column.getIsSorted() as string] ?? null}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
'flex',
|
||||||
|
header.id === 'symbol' ? 'justify-start' : 'justify-end',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{header.column.getCanSort()
|
||||||
|
? {
|
||||||
|
asc: (
|
||||||
|
<Image src='/images/sort-asc.svg' alt='mars' width={24} height={24} />
|
||||||
|
),
|
||||||
|
desc: (
|
||||||
|
<Image src='/images/sort-desc.svg' alt='mars' width={24} height={24} />
|
||||||
|
),
|
||||||
|
false: (
|
||||||
|
<Image src='/images/sort-none.svg' alt='mars' width={24} height={24} />
|
||||||
|
),
|
||||||
|
}[header.column.getIsSorted() as string] ?? null
|
||||||
|
: null}
|
||||||
|
<span>{flexRender(header.column.columnDef.header, header.getContext())}</span>
|
||||||
</div>
|
</div>
|
||||||
|
</th>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</tr>
|
||||||
))}
|
))}
|
||||||
<div className='flex flex-col gap-2'>
|
</thead>
|
||||||
{table.getRowModel().rows.length === 0 ? (
|
<tbody>
|
||||||
<div>No Data</div>
|
{table.getRowModel().rows.map((row) => {
|
||||||
) : (
|
if (row.getIsExpanded()) {
|
||||||
table.getRowModel().rows.map((row) => {
|
|
||||||
return (
|
return (
|
||||||
<AssetRow
|
<React.Fragment key={`${row.id}_subrow`}>
|
||||||
key={row.index}
|
<AssetRow key={`${row.id}_asset`} row={row} resetExpanded={table.resetExpanded} />
|
||||||
data={row.original}
|
<AssetExpanded
|
||||||
onBorrowClick={() => onBorrowClick(row.original.denom)}
|
key={`${row.id}_expanded`}
|
||||||
onRepayClick={() => onRepayClick(row.original.denom)}
|
row={row}
|
||||||
|
onBorrowClick={() => {}}
|
||||||
|
onRepayClick={() => {}}
|
||||||
|
resetExpanded={table.resetExpanded}
|
||||||
/>
|
/>
|
||||||
)
|
</React.Fragment>
|
||||||
})
|
)
|
||||||
)}
|
}
|
||||||
</div>
|
return <AssetRow key={row.index} row={row} resetExpanded={table.resetExpanded} />
|
||||||
</div>
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { getBorrowData } from 'utils/api'
|
|
||||||
|
|
||||||
export async function BorrowTable() {
|
|
||||||
const borrowData = await getBorrowData()
|
|
||||||
|
|
||||||
return borrowData.map((borrow) => {
|
|
||||||
return (
|
|
||||||
<p key={borrow.denom}>
|
|
||||||
{borrow.denom} {borrow.borrowRate} {borrow.marketLiquidity}
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
@ -2,19 +2,21 @@ import classNames from 'classnames'
|
|||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
title: string
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
className?: string
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Card = ({ children, className }: Props) => {
|
export const Card = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<section
|
||||||
className={classNames(
|
className={classNames(
|
||||||
className,
|
props.className,
|
||||||
'h-fit w-full max-w-full overflow-hidden rounded-xl border-[7px] border-accent-highlight p-4 gradient-card',
|
'h-fit w-full max-w-full overflow-hidden rounded-md border-[1px] border-white/20',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{children}
|
<div className='bg-white/10 p-4 font-semibold'>{props.title}</div>
|
||||||
</div>
|
<div className=''>{props.children}</div>
|
||||||
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@ export default function Loading(props: Props) {
|
|||||||
<div
|
<div
|
||||||
role='status'
|
role='status'
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'animate-pulse rounded-full bg-white/40',
|
'animate-pulse rounded-md bg-white/40',
|
||||||
props.className,
|
props.className,
|
||||||
props.height ? `h-${props.height}` : 'h-3',
|
props.height ? `h-[${props.height}px]` : 'h-[300px]',
|
||||||
props.width ? `w-${props.width}` : 'w-full',
|
props.width ? `w-[${props.width}px]` : 'w-full',
|
||||||
)}
|
)}
|
||||||
key={i}
|
key={i}
|
||||||
/>
|
/>
|
||||||
|
@ -20,7 +20,10 @@ export const Modal = ({ children, content, className, open, setOpen }: Props) =>
|
|||||||
return open ? (
|
return open ? (
|
||||||
<div className='fixed top-0 left-0 z-20 h-screen w-screen'>
|
<div className='fixed top-0 left-0 z-20 h-screen w-screen'>
|
||||||
<div className='relative flex h-full w-full items-center justify-center'>
|
<div className='relative flex h-full w-full items-center justify-center'>
|
||||||
<Card className={classNames('relative z-40 w-[790px] max-w-full p-0', className)}>
|
<Card
|
||||||
|
title='Modal'
|
||||||
|
className={classNames('relative z-40 w-[790px] max-w-full p-0', className)}
|
||||||
|
>
|
||||||
{setOpen && (
|
{setOpen && (
|
||||||
<span
|
<span
|
||||||
className='absolute top-4 right-4 z-50 w-[32px] text-white opacity-60 hover:cursor-pointer hover:opacity-100'
|
className='absolute top-4 right-4 z-50 w-[32px] text-white opacity-60 hover:cursor-pointer hover:opacity-100'
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
import BigNumber from 'bignumber.js'
|
|
||||||
import { useMemo, useRef, useState } from 'react'
|
|
||||||
|
|
||||||
import { BorrowTable } from 'components/Borrow/BorrowTable'
|
|
||||||
import { BorrowModal } from 'components/BorrowModal'
|
|
||||||
import { Card } from 'components/Card'
|
|
||||||
import { RepayModal } from 'components/RepayModal'
|
|
||||||
import { useAllowedCoins } from 'hooks/queries/useAllowedCoins'
|
|
||||||
import { useCreditAccountPositions } from 'hooks/queries/useCreditAccountPositions'
|
|
||||||
import { useMarkets } from 'hooks/queries/useMarkets'
|
|
||||||
import { useRedbankBalances } from 'hooks/queries/useRedbankBalances'
|
|
||||||
import { useTokenPrices } from 'hooks/queries/useTokenPrices'
|
|
||||||
import { Text } from 'components/Text'
|
|
||||||
import { getTokenDecimals, getTokenInfo } from 'utils/tokens'
|
|
||||||
import useStore from 'store'
|
|
||||||
import { getMarketAssets } from 'utils/assets'
|
|
||||||
|
|
||||||
type ModalState = {
|
|
||||||
show: 'borrow' | 'repay' | false
|
|
||||||
data: {
|
|
||||||
tokenDenom: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Borrow = () => {
|
|
||||||
const marketAssets = getMarketAssets()
|
|
||||||
|
|
||||||
const [modalState, setModalState] = useState<ModalState>({
|
|
||||||
show: false,
|
|
||||||
data: { tokenDenom: '' },
|
|
||||||
})
|
|
||||||
|
|
||||||
const selectedAccount = useStore((s) => s.selectedAccount)
|
|
||||||
|
|
||||||
const { data: allowedCoinsData } = useAllowedCoins()
|
|
||||||
const { data: positionsData } = useCreditAccountPositions(selectedAccount ?? '')
|
|
||||||
const { data: marketsData } = useMarkets()
|
|
||||||
const { data: tokenPrices } = useTokenPrices()
|
|
||||||
const { data: redbankBalances } = useRedbankBalances()
|
|
||||||
|
|
||||||
// recreate modals and reset state whenever ref changes
|
|
||||||
const modalId = useRef(0)
|
|
||||||
|
|
||||||
const borrowedAssetsMap = useMemo(() => {
|
|
||||||
let borrowedAssetsMap: Map<string, string> = new Map()
|
|
||||||
|
|
||||||
positionsData?.debts.forEach((coin) => {
|
|
||||||
borrowedAssetsMap.set(coin.denom, coin.amount)
|
|
||||||
})
|
|
||||||
|
|
||||||
return borrowedAssetsMap
|
|
||||||
}, [positionsData])
|
|
||||||
|
|
||||||
const { borrowedAssets, notBorrowedAssets } = useMemo(() => {
|
|
||||||
return {
|
|
||||||
borrowedAssets:
|
|
||||||
allowedCoinsData
|
|
||||||
?.filter((denom) => borrowedAssetsMap.has(denom))
|
|
||||||
.map((denom) => {
|
|
||||||
const { symbol, name, logo } = getTokenInfo(denom, marketAssets)
|
|
||||||
const borrowRate = Number(marketsData?.[denom].borrow_rate) || 0
|
|
||||||
const marketLiquidity = BigNumber(
|
|
||||||
redbankBalances?.find((asset) => asset.denom.toLowerCase() === denom.toLowerCase())
|
|
||||||
?.amount || 0,
|
|
||||||
)
|
|
||||||
.div(10 ** getTokenDecimals(denom, marketAssets))
|
|
||||||
.toNumber()
|
|
||||||
|
|
||||||
const borrowAmount = BigNumber(borrowedAssetsMap.get(denom) as string)
|
|
||||||
.div(10 ** getTokenDecimals(denom, marketAssets))
|
|
||||||
.toNumber()
|
|
||||||
const borrowValue = borrowAmount * (tokenPrices?.[denom] ?? 0)
|
|
||||||
|
|
||||||
const rowData = {
|
|
||||||
denom,
|
|
||||||
symbol,
|
|
||||||
logo,
|
|
||||||
name,
|
|
||||||
borrowed: {
|
|
||||||
amount: borrowAmount,
|
|
||||||
value: borrowValue,
|
|
||||||
},
|
|
||||||
borrowRate,
|
|
||||||
marketLiquidity,
|
|
||||||
}
|
|
||||||
|
|
||||||
return rowData
|
|
||||||
}) ?? [],
|
|
||||||
notBorrowedAssets:
|
|
||||||
allowedCoinsData
|
|
||||||
?.filter((denom) => !borrowedAssetsMap.has(denom))
|
|
||||||
.map((denom) => {
|
|
||||||
const { symbol, name, logo } = getTokenInfo(denom, marketAssets)
|
|
||||||
const borrowRate = Number(marketsData?.[denom].borrow_rate) || 0
|
|
||||||
const marketLiquidity = BigNumber(
|
|
||||||
redbankBalances?.find((asset) => asset.denom.toLowerCase() === denom.toLowerCase())
|
|
||||||
?.amount || 0,
|
|
||||||
)
|
|
||||||
.div(10 ** getTokenDecimals(denom, marketAssets))
|
|
||||||
.toNumber()
|
|
||||||
|
|
||||||
const rowData = {
|
|
||||||
denom,
|
|
||||||
symbol,
|
|
||||||
logo,
|
|
||||||
name,
|
|
||||||
borrowed: null,
|
|
||||||
borrowRate,
|
|
||||||
marketLiquidity,
|
|
||||||
}
|
|
||||||
|
|
||||||
return rowData
|
|
||||||
}) ?? [],
|
|
||||||
}
|
|
||||||
}, [allowedCoinsData, borrowedAssetsMap, marketsData, redbankBalances, tokenPrices, marketAssets])
|
|
||||||
|
|
||||||
const handleBorrowClick = (denom: string) => {
|
|
||||||
setModalState({ show: 'borrow', data: { tokenDenom: denom } })
|
|
||||||
modalId.current += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleRepayClick = (denom: string) => {
|
|
||||||
setModalState({ show: 'repay', data: { tokenDenom: denom } })
|
|
||||||
modalId.current += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='flex w-full items-start gap-4'>
|
|
||||||
<div className='flex-1'>
|
|
||||||
<Card className='mb-4'>
|
|
||||||
<div>
|
|
||||||
<Text tag='h3' size='xl' uppercase className='mb-7 text-center'>
|
|
||||||
Borrowings
|
|
||||||
</Text>
|
|
||||||
<BorrowTable
|
|
||||||
data={borrowedAssets}
|
|
||||||
onBorrowClick={handleBorrowClick}
|
|
||||||
onRepayClick={handleRepayClick}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
<Card>
|
|
||||||
<div>
|
|
||||||
<Text tag='h3' size='xl' uppercase className='mb-7 text-center'>
|
|
||||||
Available to Borrow
|
|
||||||
</Text>
|
|
||||||
<BorrowTable
|
|
||||||
data={notBorrowedAssets}
|
|
||||||
onBorrowClick={handleBorrowClick}
|
|
||||||
onRepayClick={handleRepayClick}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
<BorrowModal
|
|
||||||
key={`borrowModal_${modalId.current}`}
|
|
||||||
tokenDenom={modalState.data.tokenDenom}
|
|
||||||
show={modalState.show === 'borrow'}
|
|
||||||
onClose={() => setModalState({ ...modalState, show: false })}
|
|
||||||
/>
|
|
||||||
<RepayModal
|
|
||||||
key={`repayModal_${modalId.current}`}
|
|
||||||
tokenDenom={modalState.data.tokenDenom}
|
|
||||||
show={modalState.show === 'repay'}
|
|
||||||
onClose={() => setModalState({ ...modalState, show: false })}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Borrow
|
|
@ -3,6 +3,7 @@ import { NextApiRequest, NextApiResponse } from 'next'
|
|||||||
import { ENV_MISSING_MESSAGE, URL_API } from 'constants/env'
|
import { ENV_MISSING_MESSAGE, URL_API } from 'constants/env'
|
||||||
import { getMarketAssets } from 'utils/assets'
|
import { getMarketAssets } from 'utils/assets'
|
||||||
import { Coin } from '@cosmjs/stargate'
|
import { Coin } from '@cosmjs/stargate'
|
||||||
|
import BigNumber from 'bignumber.js'
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!URL_API) {
|
if (!URL_API) {
|
||||||
@ -12,18 +13,25 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
const marketAssets = getMarketAssets()
|
const marketAssets = getMarketAssets()
|
||||||
const $liquidity = fetch(`${URL_API}/markets/liquidity`)
|
const $liquidity = fetch(`${URL_API}/markets/liquidity`)
|
||||||
const $markets = fetch(`${URL_API}/markets`)
|
const $markets = fetch(`${URL_API}/markets`)
|
||||||
|
const $prices = fetch(`${URL_API}/prices`)
|
||||||
|
|
||||||
const borrow: BorrowData[] = await Promise.all([$liquidity, $markets]).then(
|
const borrow: BorrowAsset[] = await Promise.all([$liquidity, $markets, $prices]).then(
|
||||||
async ([$liquidity, $markets]) => {
|
async ([$liquidity, $markets, $prices]) => {
|
||||||
const liquidity: Coin[] = await $liquidity.json()
|
const liquidity: Coin[] = await $liquidity.json()
|
||||||
const markets: Market[] = await $markets.json()
|
const markets: Market[] = await $markets.json()
|
||||||
|
const prices: Coin[] = await $prices.json()
|
||||||
|
|
||||||
return marketAssets.map((asset) => {
|
return marketAssets.map((asset) => {
|
||||||
const currentMarket = markets.find((market) => market.denom === asset.denom)
|
const currentMarket = markets.find((market) => market.denom === asset.denom)
|
||||||
|
const price = prices.find((coin) => coin.denom === asset.denom)?.amount ?? '1'
|
||||||
|
const amount = liquidity.find((coin) => coin.denom === asset.denom)?.amount ?? '0'
|
||||||
return {
|
return {
|
||||||
denom: asset.denom,
|
denom: asset.denom,
|
||||||
borrowRate: currentMarket?.borrow_rate ?? '0',
|
borrowRate: currentMarket?.borrow_rate ?? '0',
|
||||||
marketLiquidity: liquidity.find((coin) => coin.denom === asset.denom)?.amount ?? '0',
|
liquidity: {
|
||||||
|
amount: amount,
|
||||||
|
value: new BigNumber(amount).times(price).toString(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -35,9 +43,3 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
|
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BorrowData {
|
|
||||||
denom: string
|
|
||||||
borrowRate: string
|
|
||||||
marketLiquidity: string
|
|
||||||
}
|
|
||||||
|
@ -3,6 +3,7 @@ import { NextApiRequest, NextApiResponse } from 'next'
|
|||||||
|
|
||||||
import { ADDRESS_ORACLE, ENV_MISSING_MESSAGE, URL_GQL } from 'constants/env'
|
import { ADDRESS_ORACLE, ENV_MISSING_MESSAGE, URL_GQL } from 'constants/env'
|
||||||
import { getMarketAssets } from 'utils/assets'
|
import { getMarketAssets } from 'utils/assets'
|
||||||
|
import { Coin } from '@cosmjs/stargate'
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!URL_GQL || !ADDRESS_ORACLE) {
|
if (!URL_GQL || !ADDRESS_ORACLE) {
|
||||||
@ -31,13 +32,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
|
|
||||||
const data = Object.values(result?.prices).reduce(
|
const data: Coin[] = Object.values(result?.prices).reduce((acc: Coin[], curr) => {
|
||||||
(acc, entry) => ({
|
return [...acc, { denom: curr.denom, amount: curr.price }] as Coin[]
|
||||||
...acc,
|
}, [])
|
||||||
[entry.denom]: Number(entry.price),
|
|
||||||
}),
|
|
||||||
{},
|
|
||||||
) as { [key in string]: number }
|
|
||||||
|
|
||||||
return res.status(200).json(data)
|
return res.status(200).json(data)
|
||||||
}
|
}
|
||||||
|
16
src/types/interfaces/asset.d.ts
vendored
16
src/types/interfaces/asset.d.ts
vendored
@ -15,3 +15,19 @@ interface Asset {
|
|||||||
interface OtherAsset extends Omit<Asset, 'symbol'> {
|
interface OtherAsset extends Omit<Asset, 'symbol'> {
|
||||||
symbol: 'MARS'
|
symbol: 'MARS'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BorrowAsset {
|
||||||
|
denom: string
|
||||||
|
borrowRate: string
|
||||||
|
liquidity: {
|
||||||
|
amount: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BorrowAssetActive extends BorrowAsset {
|
||||||
|
debt: {
|
||||||
|
amount: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Coin } from '@cosmjs/stargate'
|
import { Coin } from '@cosmjs/stargate'
|
||||||
import { URL_API } from 'constants/env'
|
import { URL_API } from 'constants/env'
|
||||||
import { BorrowData } from 'pages/api/markets/borrow'
|
|
||||||
|
|
||||||
export async function callAPI<T>(endpoint: string): Promise<T> {
|
export async function callAPI<T>(endpoint: string): Promise<T> {
|
||||||
const response = await fetch(`${URL_API}${endpoint}`, {
|
const response = await fetch(`${URL_API}${endpoint}`, {
|
||||||
@ -11,7 +10,7 @@ export async function callAPI<T>(endpoint: string): Promise<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getBorrowData() {
|
export async function getBorrowData() {
|
||||||
return callAPI<BorrowData[]>('/markets/borrow')
|
return callAPI<BorrowAsset[]>('/markets/borrow')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCreditAccounts(address: string) {
|
export async function getCreditAccounts(address: string) {
|
||||||
|
@ -36,7 +36,6 @@ module.exports = {
|
|||||||
fadein: 'fadein 1s ease-in-out forwards',
|
fadein: 'fadein 1s ease-in-out forwards',
|
||||||
},
|
},
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
mars: 'url(/images/bg.svg)',
|
|
||||||
'fund-modal': 'url(/images/fund-bg.webp), url(/images/fund-bg.png)',
|
'fund-modal': 'url(/images/fund-bg.webp), url(/images/fund-bg.png)',
|
||||||
'delete-modal': 'url(/images/delete-account-bg.webp), url(/images/delete-account-bg.png)',
|
'delete-modal': 'url(/images/delete-account-bg.webp), url(/images/delete-account-bg.png)',
|
||||||
'create-modal': 'url(/images/create-account-bg.webp), url(/images/create-account-bg.png)',
|
'create-modal': 'url(/images/create-account-bg.webp), url(/images/create-account-bg.png)',
|
||||||
|
Loading…
Reference in New Issue
Block a user