Merge pull request #50 from liftlearning/listing-tags

Loadings com spinner e tags de status na listagem de transações
This commit is contained in:
Ronyell Henrique authored and GitHub committed 2023-02-22 18:28:40 -03:00
commit 28e89ee9d9
16 files changed
+418 -145

No files matched your search

+16 -16
View File
@@ -1,34 +1,34 @@
<svg width="1440" height="1024" viewBox="0 0 1440 1024" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g clip-path="url(#clip0_1132_993)">
<g clip-path="url(#clip0_1163_1577)">
<rect width="1440" height="1024" transform="translate(1440 1024) rotate(-180)" fill="#111827"/>
<rect width="1440" height="1024" transform="translate(1440 1024) rotate(-180)" fill="url(#pattern0)" style="mix-blend-mode:overlay"/>
<g filter="url(#filter0_f_1132_993)">
<path d="M307.643 94.7579C329.492 66.5305 387.169 22.4938 460.177 -4.02292L471.036 -18.6088C520.484 -21.4663 630.246 -28.7619 673.711 -35.0845L744.468 -45.3771C769.739 -49.053 811.435 -55.1183 1077.82 52.5736C1130.28 96.0044 1111.85 79.416 1169.75 157.221C1227.64 235.027 1185.33 208.907 1190.2 304.059C1195.08 399.21 1178.96 376.025 1134.39 458.619C1089.82 541.213 1114.55 496.669 1027.12 544.553C939.685 592.437 946.753 578.402 834.129 598.157C721.504 617.912 727.718 597.739 655.013 598.681C582.309 599.623 602.473 587.055 541.549 580.021C480.625 572.987 475.518 564.095 412.884 544.785C350.249 525.475 367.241 522.522 283.773 473.967C200.305 425.413 275.945 417.782 226.421 367.662C176.897 317.542 217.738 305.339 208.989 242.543C200.24 179.748 227.97 198.355 242.002 174.155C256.033 149.955 285.793 122.985 307.643 94.7579Z" fill="#1E40AF"/>
<path d="M190.775 -149.087C224.734 -176.041 310.525 -217.148 415.431 -240.372L432.378 -254.317C501.523 -255.158 655.129 -257.965 716.389 -262.462L816.114 -269.782C851.731 -272.396 910.498 -276.709 1267.45 -159.904C1334.94 -114.994 1311.4 -132.083 1382.11 -53.0689C1452.82 25.945 1397.26 -1.49452 1392.03 92.5013C1386.8 186.497 1367.3 162.996 1294.87 242.638C1222.44 322.279 1262.47 279.356 1134.8 323.067C1007.13 366.778 1018.73 353.225 859.573 368.2C700.413 383.175 711.604 363.537 610.35 361.561C509.096 359.584 538.732 348.001 454.872 338.632C371.012 329.264 365.032 320.295 280.342 298.756C195.653 277.218 219.663 274.986 109.687 223.786C-0.289434 172.586 105.892 168.085 43.3311 116.698C-19.2301 65.3112 39.1224 54.9128 34.8817 -7.34067C30.6411 -69.5942 66.8656 -50.1436 89.4399 -73.4395C112.014 -96.7354 156.817 -122.133 190.775 -149.087Z" fill="#1E3A8A"/>
<g filter="url(#filter0_f_1163_1577)">
<path d="M307.642 94.7582C329.492 66.5307 387.168 22.494 460.177 -4.02267L471.036 -18.6085C520.484 -21.466 630.246 -28.7616 673.711 -35.0842L744.468 -45.3768C769.738 -49.0528 811.434 -55.118 1077.82 52.5739C1130.28 96.0046 1111.85 79.4162 1169.75 157.222C1227.64 235.027 1185.33 208.907 1190.2 304.059C1195.08 399.211 1178.96 376.025 1134.39 458.619C1089.82 541.213 1114.55 496.67 1027.12 544.553C939.684 592.437 946.753 578.403 834.129 598.157C721.504 617.912 727.718 597.74 655.013 598.681C582.309 599.623 602.473 587.055 541.549 580.021C480.625 572.987 475.518 564.095 412.883 544.785C350.249 525.475 367.241 522.522 283.773 473.967C200.305 425.413 275.945 417.782 226.421 367.662C176.897 317.542 217.738 305.339 208.989 242.544C200.24 179.748 227.97 198.355 242.001 174.155C256.033 149.955 285.793 122.986 307.642 94.7582Z" fill="#1E40AF"/>
<path d="M190.775 -149.087C224.733 -176.041 310.524 -217.148 415.43 -240.372L432.377 -254.317C501.523 -255.158 655.128 -257.966 716.388 -262.462L816.114 -269.782C851.73 -272.396 910.497 -276.709 1267.45 -159.904C1334.94 -114.994 1311.4 -132.083 1382.11 -53.069C1452.82 25.9449 1397.26 -1.49464 1392.03 92.5012C1386.8 186.497 1367.3 162.996 1294.87 242.637C1222.44 322.279 1262.47 279.355 1134.8 323.066C1007.13 366.777 1018.73 353.225 859.573 368.2C700.413 383.175 711.603 363.537 610.349 361.56C509.095 359.584 538.732 348.001 454.872 338.632C371.012 329.264 365.031 320.295 280.342 298.756C195.653 277.218 219.662 274.985 109.686 223.786C-0.289922 172.586 105.892 168.085 43.3306 116.698C-19.2306 65.311 39.1219 54.9127 34.8812 -7.34079C30.6406 -69.5943 66.8651 -50.1438 89.4394 -73.4396C112.014 -96.7355 156.816 -122.133 190.775 -149.087Z" fill="#312E81"/>
</g>
<g style="mix-blend-mode:color-burn" opacity="0.35" filter="url(#filter1_f_1132_993)">
<path d="M1352.54 698.139C1376.99 716.641 1411.79 762.434 1427.3 817.479L1440 826.73C1435.77 862.5 1427.3 941.998 1427.3 973.822L1427.3 1025.63C1427.3 1044.13 1427.3 1074.66 1284.36 1255.06C1234.51 1288.36 1253.32 1276.8 1169.15 1310.56C1084.98 1344.33 1116.49 1316.58 1022.91 1310.56C929.338 1304.55 954.26 1295.3 879.964 1255.06C805.669 1214.81 845.638 1237.02 811.312 1169.48C776.986 1101.95 789.682 1108.43 786.39 1025.63C783.099 942.831 801.907 949.307 811.312 897.038C820.716 844.769 830.121 860.496 845.638 817.478C861.156 774.461 870.56 771.685 898.303 728.668C926.046 685.65 926.517 698.139 985.765 643.095C1045.01 588.051 1041.72 643.095 1097.68 612.566C1153.63 582.038 1159.75 612.566 1222.29 612.566C1284.83 612.566 1262.73 630.606 1284.36 643.095C1305.99 655.584 1328.09 679.637 1352.54 698.139Z" fill="#93C5FD"/>
<path d="M91.3221 452.392C85.8729 433.093 176.339 405.29 222.253 393.802C265.608 378.49 362.419 348.502 402.819 351.042C453.32 354.217 491.594 367.188 576.086 375.581C660.578 383.974 712.224 406.986 879.692 451.998C1047.16 497.01 956.24 477.94 1036.56 563.955C1116.88 649.97 1079.12 612.744 1036.56 677.843C994.002 742.941 1005.47 746.666 981.601 746.666C961.798 746.666 900.661 761.818 879.692 764.843C858.723 767.867 902.898 784.219 870.91 796.843C824.704 808.719 833.843 797.843 810.486 807.343C799.682 811.737 767.491 774.203 781.992 828.393C796.493 882.583 758.426 894.935 605.326 928.873C452.227 962.811 563.6 880.704 493.906 828.356C424.213 776.008 447.488 785.204 383.41 746.666C319.331 708.128 339.315 694.563 257.058 714.864C174.802 735.165 207.416 721.441 113.43 701.123C19.4446 680.804 89.5904 669.852 80.7041 629.472C71.8177 589.091 111.037 574.169 108.353 522.953C105.668 471.737 98.1335 476.516 91.3221 452.392Z" fill="#34D399"/>
<path d="M111.594 387.022C113.259 360.564 264.221 360.352 339.494 363.553L369.947 362.69C427.921 353.376 554.055 339.062 594.79 356.315C645.71 377.881 638.936 372.07 704.334 419.736C769.731 467.403 781.379 414.05 865.631 411.662L1076.77 405.675C1180.82 402.725 1184.85 419.117 1278.51 512.502C1372.17 605.886 1199.65 577.764 1081.9 581.102C964.15 584.441 1048.4 582.052 962.463 631.008C876.524 679.964 898.995 649.315 694.745 665.11C490.496 680.905 498.576 627.154 427.165 599.666C355.753 572.179 395.937 574.041 345.588 571.967C295.238 569.893 247.569 555.238 156.348 527.812C65.1282 500.386 109.514 420.095 111.594 387.022Z" fill="#FB923C"/>
<g style="mix-blend-mode:color-burn" opacity="0.35" filter="url(#filter1_f_1163_1577)">
<path d="M1331.87 698.139C1355.95 716.641 1390.22 762.434 1405.5 817.478L1418 826.729C1413.83 862.5 1405.5 941.998 1405.5 973.822L1405.5 1025.63C1405.5 1044.13 1405.5 1074.66 1264.73 1255.06C1215.65 1288.36 1234.17 1276.8 1151.29 1310.56C1068.41 1344.33 1099.43 1316.58 1007.28 1310.56C915.14 1304.55 939.681 1295.3 866.521 1255.06C793.361 1214.81 832.719 1237.02 798.917 1169.48C765.115 1101.95 777.617 1108.43 774.376 1025.63C771.135 942.831 789.656 949.307 798.917 897.038C808.178 844.769 817.439 860.496 832.719 817.478C847.999 774.461 857.26 771.685 884.579 728.668C911.899 685.65 912.362 698.139 970.704 643.095C1029.05 588.051 1025.81 643.095 1080.91 612.566C1136.01 582.038 1142.03 612.566 1203.61 612.566C1265.2 612.566 1243.43 630.606 1264.73 643.095C1286.03 655.584 1307.8 679.637 1331.87 698.139Z" fill="#93C5FD"/>
<path d="M89.9274 452.392C84.5615 433.093 173.645 405.29 218.857 393.802C261.551 378.49 356.883 348.502 396.666 351.042C446.395 354.217 484.084 367.188 567.285 375.581C650.486 383.974 701.343 406.986 866.253 451.998C1031.16 497.01 941.631 477.94 1020.73 563.955C1099.82 649.97 1062.64 612.744 1020.73 677.843C978.817 742.941 990.104 746.666 966.604 746.666C947.104 746.666 886.901 761.818 866.253 764.843C845.604 767.867 889.105 784.219 857.604 796.843C812.105 808.719 821.104 797.843 798.104 807.343C787.465 811.737 755.766 774.203 770.045 828.393C784.325 882.583 746.839 894.934 596.079 928.873C445.319 962.811 554.99 880.704 486.361 828.356C417.732 776.008 440.652 785.204 377.552 746.666C314.453 708.128 334.131 694.563 253.132 714.864C172.132 735.165 204.248 721.441 111.698 701.123C19.148 680.804 88.2222 669.852 79.4716 629.472C70.7211 589.091 109.341 574.169 106.698 522.953C104.055 471.737 96.6348 476.516 89.9274 452.392Z" fill="#34D399"/>
<path d="M109.89 387.022C111.529 360.564 260.184 360.352 334.307 363.553L364.295 362.69C421.384 353.376 545.59 339.062 585.703 356.315C635.845 377.881 629.175 372.07 693.573 419.737C757.972 467.403 769.441 414.051 852.407 411.662L1060.32 405.675C1162.78 402.725 1166.75 419.118 1258.98 512.502C1351.2 605.886 1181.32 577.764 1065.37 581.103C949.42 584.441 1032.39 582.052 947.759 631.008C863.133 679.964 885.26 649.315 684.132 665.11C483.003 680.905 490.959 627.154 420.639 599.666C350.319 572.179 389.889 574.041 340.308 571.967C290.728 569.893 243.787 555.238 153.96 527.812C64.1335 500.386 107.841 420.095 109.89 387.022Z" fill="#FB923C"/>
</g>
</g>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="0.177778" height="0.25">
<use xlink:href="#image0_1132_993" transform="scale(0.000173611 0.000244141)"/>
<use xlink:href="#image0_1163_1577" transform="scale(0.000173611 0.000244141)"/>
</pattern>
<filter id="filter0_f_1132_993" x="-275.792" y="-560.664" width="1983.5" height="1457.53" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<filter id="filter0_f_1163_1577" x="-275.793" y="-560.664" width="1983.5" height="1457.53" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_1132_993"/>
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_1163_1577"/>
</filter>
<filter id="filter1_f_1132_993" x="-226.161" y="58.2275" width="1956.16" height="1558.77" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<filter id="filter1_f_1163_1577" x="-227.136" y="58.2273" width="1935.14" height="1558.77" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_1132_993"/>
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_1163_1577"/>
</filter>
<clipPath id="clip0_1132_993">
<clipPath id="clip0_1163_1577">
<rect width="1440" height="1024" fill="white" transform="translate(1440 1024) rotate(-180)"/>
</clipPath>
<image id="image0_1132_993" width="1024" height="1024" xlink:href="data:image/png;base64,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 truncated
<image id="image0_1163_1577" width="1024" height="1024" xlink:href="data:image/png;base64,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 truncated
</defs>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

+1 -3
View File
@@ -92,10 +92,8 @@ const withdrawDeposit = async (amount: string): Promise<any> => {
parseEther(String(amount)),
[]
);
const with_rec = await withdraw.wait();
const [t] = with_rec.events;
await withdraw.wait();
console.log(t.args);
return withdraw;
};
+2 -4
View File
@@ -10,7 +10,6 @@ import { NetworkEnum } from "@/model/NetworkEnum";
const getNetworksLiquidity = async (): Promise<void> => {
const etherStore = useEtherStore();
console.log("Loading events");
const goerliProvider = new ethers.providers.JsonRpcProvider(
import.meta.env.VITE_GOERLI_API_URL,
@@ -32,6 +31,7 @@ const getNetworksLiquidity = async (): Promise<void> => {
mumbaiProvider
);
etherStore.setLoadingNetworkLiquidity(true);
const depositListGoerli = await getValidDeposits(
getTokenAddress(NetworkEnum.ethereum),
p2pContractGoerli
@@ -43,10 +43,8 @@ const getNetworksLiquidity = async (): Promise<void> => {
);
etherStore.setDepositsValidListGoerli(depositListGoerli);
console.log(depositListGoerli);
etherStore.setDepositsValidListMumbai(depositListMumbai);
console.log(depositListMumbai);
etherStore.setLoadingNetworkLiquidity(false);
};
const getValidDeposits = async (
+53 -10
View File
@@ -5,10 +5,12 @@ import { getTokenAddress, possibleChains } from "./addresses";
import mockToken from "@/utils/smart_contract_files/MockToken.json";
import { ethers, type Event } from "ethers";
import { ethers, type Event, type BigNumber } from "ethers";
import { formatEther } from "ethers/lib/utils";
import { getValidDeposits } from "./events";
import type { ValidDeposit } from "@/model/ValidDeposit";
import type { WalletTransaction } from "@/model/WalletTransaction";
import type { UnreleasedLock } from "@/model/UnreleasedLock";
import type { Pix } from "@/model/Pix";
@@ -50,9 +52,46 @@ const listValidDepositTransactionsByWalletAddress = async (
return [];
};
const getLockStatus = async (id: [BigNumber]): Promise<number> => {
const p2pContract = getContract();
const res = await p2pContract.getLocksStatus([id]);
return res[1][0];
};
const filterLockStatus = async (
transactions: Event[]
): Promise<WalletTransaction[]> => {
const txs = await Promise.all(
transactions.map(async (transaction) => {
const tx: WalletTransaction = {
token: transaction.args?.token ? transaction.args?.token : "",
blockNumber: transaction.blockNumber ? transaction.blockNumber : -1,
amount: transaction.args?.amount
? Number(formatEther(transaction.args?.amount))
: -1,
seller: transaction.args?.seller ? transaction.args?.seller : "",
buyer: transaction.args?.buyer ? transaction.args?.buyer : "",
event: transaction.event ? transaction.event : "",
lockStatus:
transaction.event == "LockAdded"
? await getLockStatus(transaction.args?.lockID)
: -1,
transactionHash: transaction.transactionHash
? transaction.transactionHash
: "",
};
return tx;
})
);
return txs;
};
const listAllTransactionByWalletAddress = async (
walletAddress: string
): Promise<Event[]> => {
): Promise<WalletTransaction[]> => {
const p2pContract = getContract(true);
const filterDeposits = p2pContract.filters.DepositAdded([walletAddress]);
@@ -73,14 +112,18 @@ const listAllTransactionByWalletAddress = async (
filterWithdrawnDeposits
);
return [
...eventsDeposits,
...eventsAddedLocks,
...eventsReleasedLocks,
...eventsWithdrawnDeposits,
].sort((a, b) => {
return b.blockNumber - a.blockNumber;
});
const lockStatusFiltered = await filterLockStatus(
[
...eventsDeposits,
...eventsAddedLocks,
...eventsReleasedLocks,
...eventsWithdrawnDeposits,
].sort((a, b) => {
return b.blockNumber - a.blockNumber;
})
);
return lockStatusFiltered;
};
// get wallet's release transactions
@@ -1,11 +1,8 @@
<script setup lang="ts">
import CustomButton from "@/components/CustomButton/CustomButton.vue";
import ListingComponent from "@/components/ListingComponent/ListingComponent.vue";
import type { Event } from "ethers";
// props
const props = defineProps<{
lastWalletReleaseTransactions: Event[];
tokenAmount: number | undefined;
}>();
@@ -49,25 +46,6 @@ const emit = defineEmits(["makeAnotherTransaction"]);
Fazer nova transação
</button>
</div>
<div class="text-container mt-16 lg-view">
<span class="text font-extrabold text-3xl max-w-[50rem]"
>Gerenciar transações
</span>
</div>
<div class="w-full max-w-4xl lg-view">
<ListingComponent
:valid-deposits="[]"
:walletTransactions="lastWalletReleaseTransactions"
:isManageMode="false"
>
</ListingComponent>
</div>
<RouterLink
to="/transaction_history"
class="mt-8 text-white text-2xl font-bold"
>
Gerenciar Transações
</RouterLink>
</div>
</template>
+1 -1
View File
@@ -21,6 +21,6 @@ const emit = defineEmits(["buttonClicked"]);
<style scoped>
.button {
@apply rounded-lg w-full text-base font-semibold text-gray-900 py-4 bg-amber-400;
@apply rounded-lg w-full text-base font-semibold text-gray-900 p-4 bg-amber-400;
}
</style>
@@ -2,26 +2,54 @@
import { withdrawDeposit } from "@/blockchain/buyerMethods";
import { NetworkEnum } from "@/model/NetworkEnum";
import type { ValidDeposit } from "@/model/ValidDeposit";
import type { WalletTransaction } from "@/model/WalletTransaction";
import { useEtherStore } from "@/store/ether";
import { formatEther } from "@ethersproject/units";
import type { BigNumber, Event } from "ethers";
import { storeToRefs } from "pinia";
import { ref, watch } from "vue";
import SpinnerComponent from "../SpinnerComponent.vue";
import { decimalCount } from "@/utils/decimalCount";
import { debounce } from "@/utils/debounce";
const etherStore = useEtherStore();
// props
const props = defineProps<{
validDeposits: ValidDeposit[];
walletTransactions: Event[];
walletTransactions: WalletTransaction[];
}>();
const emit = defineEmits(["depositWithdrawn"]);
const etherStore = useEtherStore();
const itemsToShow = ref<Event[]>([]);
const { loadingWalletTransactions } = storeToRefs(etherStore);
const remaining = ref<number>(0.0);
const itemsToShow = ref<WalletTransaction[]>([]);
const withdrawAmount = ref<string>("");
const withdrawButtonOpacity = ref<number>(0.6);
const withdrawButtonCursor = ref<string>("not-allowed");
const isCollapsibleOpen = ref<boolean>(false);
const validDecimals = ref<boolean>(true);
const validWithdrawAmount = ref<boolean>(true);
const enableConfirmButton = ref<boolean>(false);
// Debounce methods
const handleInputEvent = (event: any): void => {
const { value } = event.target;
if (decimalCount(String(value)) > 2) {
validDecimals.value = false;
enableConfirmButton.value = false;
return;
}
validDecimals.value = true;
if (value > remaining.value) {
validWithdrawAmount.value = false;
enableConfirmButton.value = false;
return;
}
validWithdrawAmount.value = true;
enableConfirmButton.value = true;
};
const callWithdraw = async () => {
if (withdrawAmount.value) {
@@ -49,6 +77,7 @@ const getRemaining = (): number => {
// Here we are getting only the first element of the list because
// in this release only the BRL token is being used.
const deposit = props.validDeposits[0];
remaining.value = deposit ? deposit.remaining : 0;
return deposit ? deposit.remaining : 0;
}
return 0;
@@ -93,11 +122,6 @@ const getEventName = (event: string | undefined): string => {
return possibleEventName[event];
};
const getAmountFormatted = (amount?: BigNumber): string => {
if (!amount) return "";
return formatEther(amount);
};
// watch props changes
watch(props, async (): Promise<void> => {
const itemsToShowQty = itemsToShow.value.length;
@@ -114,8 +138,14 @@ showInitialItems();
</script>
<template>
<div class="blur-container">
<div class="w-full bg-white p-6 rounded-lg">
<div class="blur-container" v-if="loadingWalletTransactions">
<SpinnerComponent width="8" height="8" fillColor="white"></SpinnerComponent>
</div>
<div class="blur-container" v-if="!loadingWalletTransactions">
<div
class="w-full bg-white p-6 rounded-lg"
v-if="props.validDeposits.length > 0"
>
<div class="flex justify-between items-center">
<div>
<p class="text-sm leading-5 font-medium text-gray-600">
@@ -143,11 +173,22 @@ showInitialItems();
type="number"
name=""
id=""
@input="debounce(handleInputEvent, 500)($event)"
placeholder="0"
class="text-2xl text-gray-900 w-full outline-none"
v-model="withdrawAmount"
/>
</div>
<div class="flex justify-center" v-if="!validDecimals">
<span class="text-red-500 font-normal text-sm"
>Por favor utilize no máximo 2 casas decimais</span
>
</div>
<div class="flex justify-center" v-else-if="!validWithdrawAmount">
<span class="text-red-500 font-normal text-sm"
>Saldo insuficiente</span
>
</div>
<hr v-show="isCollapsibleOpen" class="pb-3" />
<div
v-show="isCollapsibleOpen"
@@ -159,7 +200,9 @@ showInitialItems();
>
Cancelar
</h1>
<div
v-if="enableConfirmButton"
class="withdraw-button flex gap-2 items-center justify-self-center border-2 p-2 border-amber-300 rounded-md"
@click="callWithdraw"
>
@@ -180,18 +223,36 @@ showInitialItems();
{{ getEventName(item.event) }}
</p>
<p class="text-xl leading-7 font-semibold text-gray-900">
{{ getAmountFormatted(item.args?.amount) }}
{{ item.amount }}
BRZ
</p>
<p class="text-xs leading-4 font-medium text-gray-600"></p>
</div>
<div>
<div class="bg-emerald-300 rounded-lg text-center mb-2 p-1">
<div
class="bg-amber-300 status-text"
v-if="getEventName(item.event) == 'Reserva' && item.lockStatus == 1"
>
Ativo
</div>
<div
class="bg-[#94A3B8] status-text"
v-if="getEventName(item.event) == 'Reserva' && item.lockStatus == 2"
>
Expirado
</div>
<div
class="bg-emerald-300 status-text"
v-if="
(getEventName(item.event) == 'Reserva' && item.lockStatus == 3) ||
getEventName(item.event) != 'Reserva'
"
>
Finalizado
</div>
<div
class="flex gap-2 cursor-pointer items-center justify-self-center"
@click="openEtherscanUrl(item?.transactionHash)"
@click="openEtherscanUrl(item.transactionHash)"
>
<span class="last-release-info">{{ getExplorer() }}</span>
<img alt="Redirect image" src="@/assets/redirect.svg" />
@@ -242,6 +303,9 @@ p {
@apply flex justify-between items-center;
}
.status-text {
@apply text-base font-medium text-gray-900 rounded-lg text-center mb-2 p-1;
}
.text {
@apply text-white text-center;
}
@@ -3,11 +3,13 @@ import ListingComponent from "@/components/ListingComponent/ListingComponent.vue
import { createPinia, setActivePinia } from "pinia";
import { expect } from "vitest";
import { MockValidDeposits } from "@/model/mock/ValidDepositMock";
import { MockEvents } from "@/model/mock/EventMock";
import { MockWalletTransactions } from "@/model/mock/WalletTransactionMock";
import { useEtherStore } from "@/store/ether";
describe("ListingComponent.vue", () => {
beforeEach(() => {
setActivePinia(createPinia());
useEtherStore().setLoadingWalletTransactions(false);
});
test("Test Message when an empty array is received", () => {
@@ -25,7 +27,7 @@ describe("ListingComponent.vue", () => {
const wrapper = mount(ListingComponent, {
props: {
validDeposits: [],
walletTransactions: MockEvents,
walletTransactions: MockWalletTransactions,
},
});
@@ -38,7 +40,7 @@ describe("ListingComponent.vue", () => {
const wrapper = mount(ListingComponent, {
props: {
validDeposits: MockValidDeposits,
walletTransactions: MockEvents,
walletTransactions: MockWalletTransactions,
},
});
const btn = wrapper.find("button");
@@ -50,14 +52,14 @@ describe("ListingComponent.vue", () => {
elements = wrapper.findAll(".item-container");
expect(elements).toHaveLength(4);
expect(elements).toHaveLength(5);
});
test("Test withdraw offer button emit", async () => {
const wrapper = mount(ListingComponent, {
props: {
validDeposits: MockValidDeposits,
walletTransactions: MockEvents,
walletTransactions: MockWalletTransactions,
},
});
wrapper.vm.$emit("depositWithdrawn");
+28 -4
View File
@@ -9,6 +9,7 @@ import { verifyNetworkLiquidity } from "@/utils/networkLiquidity";
import { NetworkEnum } from "@/model/NetworkEnum";
import type { ValidDeposit } from "@/model/ValidDeposit";
import { decimalCount } from "@/utils/decimalCount";
import SpinnerComponent from "./SpinnerComponent.vue";
// Store reference
const etherStore = useEtherStore();
@@ -18,6 +19,7 @@ const {
networkName,
depositsValidListGoerli,
depositsValidListMumbai,
loadingNetworkLiquidity,
} = storeToRefs(etherStore);
// Reactive state
@@ -160,8 +162,11 @@ watch(walletAddress, (): void => {
</div>
</div>
<div class="custom-divide py-2"></div>
<div class="flex justify-between pt-2" v-if="hasLiquidity">
<div class="custom-divide py-2 mb-2"></div>
<div
class="flex justify-between"
v-if="hasLiquidity && !loadingNetworkLiquidity"
>
<p class="text-gray-500 font-normal text-sm w-auto">
~ R$ {{ tokenValue.toFixed(2) }}
</p>
@@ -182,12 +187,31 @@ watch(walletAddress, (): void => {
/>
</div>
</div>
<div class="flex pt-2 justify-center" v-if="!validDecimals">
<div
class="flex justify-center items-center"
v-if="loadingNetworkLiquidity"
>
<span class="text-gray-900 font-normal text-sm mr-2"
>Carregando liquidez das redes.</span
>
<SpinnerComponent
width="4"
height="4"
fillColor="white"
></SpinnerComponent>
</div>
<div
class="flex justify-center"
v-if="!validDecimals && !loadingNetworkLiquidity"
>
<span class="text-red-500 font-normal text-sm"
>Por favor utilize no máximo 2 casas decimais</span
>
</div>
<div class="flex pt-2 justify-center" v-else-if="!hasLiquidity">
<div
class="flex justify-center"
v-else-if="!hasLiquidity && !loadingNetworkLiquidity"
>
<span class="text-red-500 font-normal text-sm"
>Atualmente não há liquidez nas redes para sua demanda</span
>
+41
View File
@@ -0,0 +1,41 @@
<script setup lang="ts">
// prop
const props = defineProps({
width: String,
height: String,
fillColor: String,
show: Boolean,
});
const getCustomClass = () => {
return [
`w-${props.width}`,
`h-${props.height}`,
`fill-${props.fillColor}`,
"text-gray-200",
"animate-spin",
"dark:text-gray-600",
];
};
</script>
<template>
<div v-if="props.show ? props.show : true">
<svg
aria-hidden="true"
:class="getCustomClass()"
viewBox="0 0 100 101"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
fill="currentColor"
/>
<path
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
fill="currentFill"
/>
</svg>
</div>
</template>
+4 -2
View File
@@ -118,7 +118,9 @@ onClickOutside(infoMenuRef, () => {
:to="'/faq'"
class="menu-button gap-2 px-4 rounded-md cursor-pointer"
>
<span class="text-gray-900 py-4 text-end font-semibold text-sm whitespace-nowrap">
<span
class="text-gray-900 py-4 text-end font-semibold text-sm whitespace-nowrap"
>
Perguntas frequentes
</span>
</RouterLink>
@@ -357,7 +359,7 @@ onClickOutside(infoMenuRef, () => {
{{ formatWalletAddress() }}
</span>
<img
class="text-gray-900 lg-view"
class="text-gray-900"
v-if="!menuHoverToggle && !menuOpenToggle"
alt="Chevron Down"
src="@/assets/chevronDown.svg"
+10
View File
@@ -0,0 +1,10 @@
export type WalletTransaction = {
token: string;
blockNumber: number;
amount: number;
seller: string;
buyer: string;
event: string;
lockStatus: number;
transactionHash: string;
};
+54
View File
@@ -0,0 +1,54 @@
import type { WalletTransaction } from "../WalletTransaction";
export const MockWalletTransactions: WalletTransaction[] = [
{
blockNumber: 1,
token: "1",
amount: 70,
seller: "mockedSellerAddress",
buyer: "mockedBuyerAddress",
event: "Deposit",
lockStatus: 0,
transactionHash: "1",
},
{
blockNumber: 2,
token: "2",
amount: 200,
seller: "mockedSellerAddress",
buyer: "mockedBuyerAddress",
event: "Lock",
lockStatus: 1,
transactionHash: "2",
},
{
blockNumber: 3,
token: "3",
amount: 1250,
seller: "mockedSellerAddress",
buyer: "mockedBuyerAddress",
event: "Release",
lockStatus: 2,
transactionHash: "3",
},
{
blockNumber: 4,
token: "4",
amount: 4000,
seller: "mockedSellerAddress",
buyer: "mockedBuyerAddress",
event: "Deposit",
lockStatus: 0,
transactionHash: "4",
},
{
blockNumber: 5,
token: "5",
amount: 2000,
seller: "mockedSellerAddress",
buyer: "mockedBuyerAddress",
event: "Deposit",
lockStatus: 3,
transactionHash: "5",
},
];
+8
View File
@@ -13,6 +13,8 @@ export const useEtherStore = defineStore("ether", {
depositsValidListGoerli: [] as ValidDeposit[],
// Depósitos válidos para compra MUMBAI
depositsValidListMumbai: [] as ValidDeposit[],
loadingWalletTransactions: false,
loadingNetworkLiquidity: false,
}),
actions: {
setWalletAddress(walletAddress: string) {
@@ -36,6 +38,12 @@ export const useEtherStore = defineStore("ether", {
setDepositsValidListMumbai(depositsValidList: ValidDeposit[]) {
this.depositsValidListMumbai = depositsValidList;
},
setLoadingWalletTransactions(isLoadingWalletTransactions: boolean) {
this.loadingWalletTransactions = isLoadingWalletTransactions;
},
setLoadingNetworkLiquidity(isLoadingNetworkLiquidity: boolean) {
this.loadingNetworkLiquidity = isLoadingNetworkLiquidity;
},
},
// Alterar para integrar com mumbai
getters: {
+63 -17
View File
@@ -2,20 +2,26 @@
import SearchComponent from "@/components/SearchComponent.vue";
import LoadingComponent from "@/components/LoadingComponent/LoadingComponent.vue";
import BuyConfirmedComponent from "@/components/BuyConfirmedComponent/BuyConfirmedComponent.vue";
import ListingComponent from "@/components/ListingComponent/ListingComponent.vue";
import { ref, onMounted, watch } from "vue";
import { useEtherStore } from "@/store/ether";
import QrCodeComponent from "@/components/QrCodeComponent.vue";
import CustomModal from "@/components/CustomModal/CustomModal.vue";
import { storeToRefs } from "pinia";
import { addLock, releaseLock } from "@/blockchain/buyerMethods";
import {
addLock,
releaseLock,
withdrawDeposit,
} from "@/blockchain/buyerMethods";
import {
updateWalletStatus,
listReleaseTransactionByWalletAddress,
listAllTransactionByWalletAddress,
checkUnreleasedLock,
listValidDepositTransactionsByWalletAddress,
} from "@/blockchain/wallet";
import { getNetworksLiquidity } from "@/blockchain/events";
import type { Event } from "ethers";
import type { ValidDeposit } from "@/model/ValidDeposit";
import type { WalletTransaction } from "@/model/WalletTransaction";
enum Step {
Search,
@@ -34,7 +40,8 @@ const tokenAmount = ref<number>();
const lockID = ref<string>("");
const loadingRelease = ref<boolean>(false);
const showModal = ref<boolean>(false);
const lastWalletReleaseTransactions = ref<Event[]>([]);
const lastWalletTransactions = ref<WalletTransaction[]>([]);
const depositList = ref<ValidDeposit[]>([]);
const confirmBuyClick = async (
selectedDeposit: ValidDeposit,
@@ -75,21 +82,50 @@ const releaseTransaction = async (e2eId: string) => {
);
release.wait();
await listReleaseTransactionByWalletAddress(
walletAddress.value.toLowerCase()
).then((releaseTransactions) => {
if (releaseTransactions)
lastWalletReleaseTransactions.value = releaseTransactions;
});
await getWalletTransactions();
await updateWalletStatus();
loadingRelease.value = false;
}
};
const getWalletTransactions = async () => {
etherStore.setLoadingWalletTransactions(true);
if (walletAddress.value) {
const walletDeposits = await listValidDepositTransactionsByWalletAddress(
walletAddress.value
);
const allUserTransactions = await listAllTransactionByWalletAddress(
walletAddress.value
);
if (walletDeposits) {
depositList.value = walletDeposits;
}
if (allUserTransactions) {
lastWalletTransactions.value = allUserTransactions;
}
}
etherStore.setLoadingWalletTransactions(false);
};
const callWithdraw = async (amount: string) => {
if (amount) {
etherStore.setLoadingWalletTransactions(true);
const withdraw = await withdrawDeposit(amount);
if (withdraw) {
console.log("Saque realizado!");
await getWalletTransactions();
} else {
console.log("Não foi possível realizar o saque!");
}
etherStore.setLoadingWalletTransactions(false);
}
};
const checkForUnreleasedLocks = async (): Promise<void> => {
const walletLocks = await checkUnreleasedLock(walletAddress.value);
console.log(walletLocks);
if (walletLocks) {
lockID.value = walletLocks.lockID;
tokenAmount.value = walletLocks.pix.value;
@@ -142,12 +178,22 @@ onMounted(async () => {
/>
</div>
<div v-if="flowStep == Step.List">
<BuyConfirmedComponent
v-if="!loadingRelease"
:last-wallet-release-transactions="lastWalletReleaseTransactions"
:tokenAmount="tokenAmount"
@make-another-transaction="flowStep = Step.Search"
/>
<div class="flex flex-col gap-10" v-if="!loadingRelease">
<BuyConfirmedComponent
:tokenAmount="tokenAmount"
@make-another-transaction="flowStep = Step.Search"
/>
<div
class="text-3xl text-white leading-9 font-bold justify-center flex mt-4"
>
Gerenciar transações
</div>
<ListingComponent
:valid-deposits="depositList"
:wallet-transactions="lastWalletTransactions"
@deposit-withdrawn="callWithdraw"
></ListingComponent>
</div>
<LoadingComponent
v-if="loadingRelease"
:message="'A transação está sendo enviada para a rede. Em breve os tokens serão depositados em sua carteira.'"
+50 -45
View File
@@ -2,33 +2,48 @@
import { useEtherStore } from "@/store/ether";
import { storeToRefs } from "pinia";
import ListingComponent from "@/components/ListingComponent/ListingComponent.vue";
import LoadingComponent from "@/components/LoadingComponent/LoadingComponent.vue";
import { ref, watch, onMounted } from "vue";
import {
listValidDepositTransactionsByWalletAddress,
listAllTransactionByWalletAddress,
} from "@/blockchain/wallet";
import { withdrawDeposit } from "@/blockchain/buyerMethods";
import type { ValidDeposit } from "@/model/ValidDeposit";
import type { Event } from "ethers";
import type { WalletTransaction } from "@/model/WalletTransaction";
import router from "@/router/index";
const etherStore = useEtherStore();
const { walletAddress, networkName } = storeToRefs(etherStore);
const loadingWithdraw = ref<boolean>(false);
const depositList = ref<ValidDeposit[]>([]);
const transactionsList = ref<Event[]>([]);
const transactionsList = ref<WalletTransaction[]>([]);
const updateRemaining = async () => {
const walletDeposits = await listValidDepositTransactionsByWalletAddress(
walletAddress.value
);
depositList.value = walletDeposits;
const callWithdraw = async (amount: string) => {
if (amount) {
loadingWithdraw.value = true;
let withdraw;
try {
withdraw = await withdrawDeposit(amount);
} catch {
loadingWithdraw.value = false;
}
const allUserTransactions = await listAllTransactionByWalletAddress(
walletAddress.value
);
transactionsList.value = allUserTransactions;
if (withdraw) {
console.log("Saque realizado!");
await getWalletTransactions();
} else {
console.log("Não foi possível realizar o saque!");
}
loadingWithdraw.value = false;
}
};
onMounted(async () => {
const getWalletTransactions = async () => {
etherStore.setLoadingWalletTransactions(true);
if (walletAddress.value) {
const walletDeposits = await listValidDepositTransactionsByWalletAddress(
walletAddress.value
@@ -45,54 +60,44 @@ onMounted(async () => {
transactionsList.value = allUserTransactions;
}
}
etherStore.setLoadingWalletTransactions(false);
};
onMounted(async () => {
if (!walletAddress.value) {
router.push({ name: "home" });
}
await getWalletTransactions();
});
watch(walletAddress, async (newValue) => {
await listValidDepositTransactionsByWalletAddress(newValue)
.then((res) => {
if (res) depositList.value = res;
})
.catch(() => {
depositList.value = [];
});
await listAllTransactionByWalletAddress(newValue)
.then((res) => {
if (res) transactionsList.value = res;
})
.catch(() => {
transactionsList.value = [];
});
watch(walletAddress, async () => {
await getWalletTransactions();
});
watch(networkName, async () => {
await listValidDepositTransactionsByWalletAddress(walletAddress.value)
.then((res) => {
if (res) depositList.value = res;
})
.catch(() => {
depositList.value = [];
});
await listAllTransactionByWalletAddress(walletAddress.value)
.then((res) => {
if (res) transactionsList.value = res;
})
.catch(() => {
transactionsList.value = [];
});
await getWalletTransactions();
});
</script>
<template>
<div class="page">
<div class="header">Gerenciar Ofertas</div>
<div class="header" v-if="!loadingWithdraw && !walletAddress">
Por Favor Conecte Sua Carteira
</div>
<div class="header" v-if="!loadingWithdraw && walletAddress">
Gerenciar Ofertas
</div>
<div class="w-full max-w-4xl">
<ListingComponent
v-if="!loadingWithdraw && walletAddress"
:valid-deposits="depositList"
:wallet-transactions="transactionsList"
@deposit-withdrawn="updateRemaining"
@deposit-withdrawn="callWithdraw"
></ListingComponent>
<LoadingComponent
v-if="loadingWithdraw"
:message="'A transação está sendo enviada para a rede. Em breve os tokens serão depositados em sua carteira.'"
/>
</div>
</div>
</template>