commit
b9dd4a7621
4
src/assets/closeAlertIcon.svg
Normal file
4
src/assets/closeAlertIcon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.0105 1.69682C13.2058 1.50155 13.2058 1.18497 13.0105 0.989708C12.8153 0.794446 12.4987 0.794446 12.3034 0.989708L7.00016 6.29297L1.6969 0.989708C1.50163 0.794446 1.18505 0.794446 0.989788 0.989708C0.794526 1.18497 0.794526 1.50155 0.989788 1.69682L6.29305 7.00008L0.989708 12.3034C0.794446 12.4987 0.794446 12.8153 0.989708 13.0105C1.18497 13.2058 1.50155 13.2058 1.69681 13.0105L7.00016 7.70718L12.3035 13.0105C12.4988 13.2058 12.8153 13.2058 13.0106 13.0105C13.2059 12.8153 13.2059 12.4987 13.0106 12.3034L7.70726 7.00008L13.0105 1.69682Z" fill="#1F2937"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.636235 0.636155C1.02676 0.245631 1.65992 0.245631 2.05045 0.636155L7.00016 5.58586L11.9499 0.636155C12.3404 0.245631 12.9736 0.245631 13.3641 0.636155C13.7546 1.02668 13.7546 1.65984 13.3641 2.05037L8.41437 7.00008L13.3642 11.9499C13.7547 12.3404 13.7547 12.9736 13.3642 13.3641C12.9736 13.7546 12.3405 13.7546 11.9499 13.3641L7.00016 8.41429L2.05037 13.3641C1.65984 13.7546 1.02668 13.7546 0.636155 13.3641C0.245632 12.9736 0.24563 12.3404 0.636154 11.9499L5.58594 7.00008L0.636235 2.05037C0.245711 1.65984 0.245711 1.02668 0.636235 0.636155Z" fill="#1F2937"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -7,6 +7,8 @@ import { getContract } from "./provider";
|
||||
import type { ValidDeposit } from "@/model/ValidDeposit";
|
||||
import { getP2PixAddress, getTokenAddress } from "./addresses";
|
||||
import { NetworkEnum } from "@/model/NetworkEnum";
|
||||
import type { UnreleasedLock } from "@/model/UnreleasedLock";
|
||||
import type { Pix } from "@/model/Pix";
|
||||
|
||||
const getNetworksLiquidity = async (): Promise<void> => {
|
||||
const etherStore = useEtherStore();
|
||||
@ -100,4 +102,25 @@ const getValidDeposits = async (
|
||||
return Object.values(depositList);
|
||||
};
|
||||
|
||||
export { getValidDeposits, getNetworksLiquidity };
|
||||
const getUnreleasedLockById = async (
|
||||
lockID: string
|
||||
): Promise<UnreleasedLock> => {
|
||||
const p2pContract = getContract();
|
||||
const pixData: Pix = {
|
||||
pixKey: "",
|
||||
};
|
||||
|
||||
const lock = await p2pContract.mapLocks(lockID);
|
||||
|
||||
const pixTarget = lock.pixTarget;
|
||||
const amount = formatEther(lock?.amount);
|
||||
pixData.pixKey = String(Number(pixTarget));
|
||||
pixData.value = Number(amount);
|
||||
|
||||
return {
|
||||
lockID: lockID,
|
||||
pix: pixData,
|
||||
};
|
||||
};
|
||||
|
||||
export { getValidDeposits, getNetworksLiquidity, getUnreleasedLockById };
|
||||
|
@ -80,6 +80,9 @@ const filterLockStatus = async (
|
||||
transactionHash: transaction.transactionHash
|
||||
? transaction.transactionHash
|
||||
: "",
|
||||
transactionID: transaction.args?.lockID
|
||||
? String(transaction.args?.lockID)
|
||||
: "",
|
||||
};
|
||||
|
||||
return tx;
|
||||
|
154
src/components/CustomAlert/CustomAlert.vue
Normal file
154
src/components/CustomAlert/CustomAlert.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
const props = defineProps<{
|
||||
type: string;
|
||||
}>();
|
||||
|
||||
const alertText = ref<string>("");
|
||||
const alertPaddingLeft = ref<string>("18rem");
|
||||
|
||||
if (props.type === "sell") {
|
||||
alertPaddingLeft.value = "30%";
|
||||
} else if (props.type === "buy") {
|
||||
alertPaddingLeft.value = "30%";
|
||||
} else if (props.type === "withdraw") {
|
||||
alertPaddingLeft.value = "40%";
|
||||
} else if (props.type === "redirect") {
|
||||
alertPaddingLeft.value = "35%";
|
||||
}
|
||||
|
||||
switch (props.type) {
|
||||
case "buy":
|
||||
alertText.value =
|
||||
"Tudo certo! Os tokens já foram retirados da oferta e estão disponíveis na sua carteira.";
|
||||
break;
|
||||
case "sell":
|
||||
alertText.value =
|
||||
"Tudo certo! Os tokens já foram reservados e sua oferta está disponível.";
|
||||
break;
|
||||
case "redirect":
|
||||
alertText.value = "Existe uma compra em aberto. Continuar?";
|
||||
break;
|
||||
case "withdraw":
|
||||
alertText.value = "Tudo certo! Saque realizado com sucesso!";
|
||||
break;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
class="modal-overlay sm:h-12 h-full inset-0 absolute backdrop-blur-sm sm:backdrop-blur-none"
|
||||
>
|
||||
<div class="modal px-12 pl-72 text-center sm:flex justify-between hidden">
|
||||
<div class="flex items-center">
|
||||
<p class="text-black tracking-tighter leading-tight my-2">
|
||||
{{ alertText }}
|
||||
</p>
|
||||
<button v-if="props.type === 'redirect'" @click="$emit('go-to-lock')">
|
||||
Sim
|
||||
</button>
|
||||
</div>
|
||||
<img
|
||||
src="../../assets/closeAlertIcon.svg"
|
||||
alt="close alert"
|
||||
class="w-3 cursor-pointer"
|
||||
@click="$emit('close-alert')"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="modal-mobile px-7 py-3 text-center inline-block sm:hidden mt-24 h-48"
|
||||
v-if="props.type !== 'redirect'"
|
||||
>
|
||||
<p class="text-black tracking-tighter leading-tight my-2 text-start mb-4">
|
||||
{{ alertText }}
|
||||
</p>
|
||||
<button
|
||||
@click="$emit('close-alert')"
|
||||
class="border-2 border-solid border-amber-400 mt-2"
|
||||
>
|
||||
Ok
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="modal-mobile px-5 text-center inline-block sm:hidden mt-24 h-40"
|
||||
v-if="props.type === 'redirect'"
|
||||
>
|
||||
<p
|
||||
class="text-black text-lg tracking-tighter leading-tight my-6 mx-2 text-justify font-semibold"
|
||||
>
|
||||
Retomar a última compra?
|
||||
</p>
|
||||
<div class="flex justify-around items-center px-2">
|
||||
<button
|
||||
@click="$emit('close-alert')"
|
||||
class="border-2 border-solid border-white-400 mt-2 font-semibold"
|
||||
>
|
||||
Não
|
||||
</button>
|
||||
<button
|
||||
@click="$emit('go-to-lock')"
|
||||
class="border-2 border-solid border-white-400 mt-2 font-semibold"
|
||||
>
|
||||
Sim
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.modal-overlay {
|
||||
display: flex !important;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding-top: 7rem;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.modal {
|
||||
background-color: rgba(251, 191, 36, 1);
|
||||
height: 3rem;
|
||||
width: 96%;
|
||||
border-radius: 10px;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
padding-left: v-bind(alertPaddingLeft);
|
||||
}
|
||||
|
||||
.modal-mobile {
|
||||
background-color: rgba(251, 191, 36, 1);
|
||||
/* height: 200px; */
|
||||
width: 300px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.close {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.close-img {
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
.check {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-weight: 500;
|
||||
font-size: 28px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
color: black;
|
||||
font-size: 16px;
|
||||
border-radius: 10px;
|
||||
border: 2px solid white;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
</style>
|
@ -59,19 +59,22 @@ const handleInputEvent = (event: any): void => {
|
||||
enableConfirmButton.value = true;
|
||||
};
|
||||
|
||||
const callWithdraw = async () => {
|
||||
if (withdrawAmount.value) {
|
||||
const withdraw = await withdrawDeposit(withdrawAmount.value);
|
||||
if (withdraw) {
|
||||
console.log(withdraw);
|
||||
alert("Saque realizado!");
|
||||
emit("depositWithdrawn");
|
||||
}
|
||||
}
|
||||
const callWithdraw = () => {
|
||||
emit("depositWithdrawn", withdrawAmount.value);
|
||||
};
|
||||
|
||||
watch(enableConfirmButton, (): void => {
|
||||
if (!enableConfirmButton.value) {
|
||||
withdrawButtonOpacity.value = 0.7;
|
||||
withdrawButtonCursor.value = "not-allowed";
|
||||
} else {
|
||||
withdrawButtonOpacity.value = 1;
|
||||
withdrawButtonCursor.value = "pointer";
|
||||
}
|
||||
});
|
||||
|
||||
watch(withdrawAmount, (): void => {
|
||||
if (!withdrawAmount.value) {
|
||||
if (!withdrawAmount.value || !enableConfirmButton.value) {
|
||||
withdrawButtonOpacity.value = 0.7;
|
||||
withdrawButtonCursor.value = "not-allowed";
|
||||
} else {
|
||||
@ -174,7 +177,7 @@ showInitialItems();
|
||||
<p class="text-xl leading-7 font-semibold text-gray-900">
|
||||
{{ getRemaining() }} BRZ
|
||||
</p>
|
||||
<div class="flex gap-2 w-32 sm:w-44" v-if="activeLockAmount != 0">
|
||||
<div class="flex gap-2 w-32 sm:w-56" v-if="activeLockAmount != 0">
|
||||
<span class="text-xs font-normal text-gray-400" ref="infoText">{{
|
||||
`com ${activeLockAmount.toFixed(2)} BRZ em lock`
|
||||
}}</span>
|
||||
@ -252,7 +255,6 @@ showInitialItems();
|
||||
</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"
|
||||
>
|
||||
@ -272,22 +274,23 @@ showInitialItems();
|
||||
:key="item.blockNumber"
|
||||
>
|
||||
<div class="item-container">
|
||||
<div>
|
||||
<p class="text-sm leading-5 font-medium text-gray-600">
|
||||
<div class="flex flex-col self-start">
|
||||
<span class="text-xs sm:text-sm leading-5 font-medium text-gray-600">
|
||||
{{ getEventName(item.event) }}
|
||||
</p>
|
||||
<p class="text-xl leading-7 font-semibold text-gray-900">
|
||||
</span>
|
||||
<span
|
||||
class="text-xl sm:text-xl leading-7 font-semibold text-gray-900"
|
||||
>
|
||||
{{ item.amount }}
|
||||
BRZ
|
||||
</p>
|
||||
<p class="text-xs leading-4 font-medium text-gray-600"></p>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="bg-amber-300 status-text"
|
||||
v-if="getEventName(item.event) == 'Reserva' && item.lockStatus == 1"
|
||||
>
|
||||
Ativo
|
||||
Em Aberto
|
||||
</div>
|
||||
<div
|
||||
class="bg-[#94A3B8] status-text"
|
||||
@ -305,11 +308,30 @@ showInitialItems();
|
||||
Finalizado
|
||||
</div>
|
||||
<div
|
||||
class="flex gap-2 cursor-pointer items-center justify-self-center"
|
||||
class="flex gap-2 cursor-pointer items-center justify-self-center w-full"
|
||||
@click="openEtherscanUrl(item.transactionHash)"
|
||||
v-if="getEventName(item.event) != 'Reserva' || item.lockStatus != 1"
|
||||
>
|
||||
<span class="last-release-info">{{ getExplorer() }}</span>
|
||||
<img alt="Redirect image" src="@/assets/redirect.svg" />
|
||||
<img
|
||||
alt="Redirect image"
|
||||
src="@/assets/redirect.svg"
|
||||
class="w-3 h-3 sm:w-4 sm:h-4"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="flex gap-2 justify-self-center w-full"
|
||||
v-if="getEventName(item.event) == 'Reserva' && item.lockStatus == 1"
|
||||
>
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'home',
|
||||
force: true,
|
||||
state: { lockID: item.transactionID },
|
||||
}"
|
||||
class="router-button"
|
||||
>Continuar</RouterLink
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -358,7 +380,7 @@ p {
|
||||
}
|
||||
|
||||
.status-text {
|
||||
@apply text-base font-medium text-gray-900 rounded-lg text-center mb-2 p-1;
|
||||
@apply text-xs sm:text-base font-medium text-gray-900 rounded-lg text-center mb-2 px-2 py-1 mt-4;
|
||||
}
|
||||
.text {
|
||||
@apply text-white text-center;
|
||||
@ -373,13 +395,17 @@ p {
|
||||
}
|
||||
|
||||
.last-release-info {
|
||||
@apply font-medium text-sm sm:text-base text-gray-900 justify-self-center;
|
||||
@apply font-medium text-xs sm:text-sm text-gray-900 justify-self-center;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
@apply bg-white text-gray-900 font-medium text-xs md:text-base px-3 py-2 rounded border-2 border-emerald-500 left-5 top-[-3rem];
|
||||
}
|
||||
|
||||
.router-button {
|
||||
@apply rounded-lg border-amber-300 border-2 px-3 py-2 text-gray-900 font-semibold sm:text-base text-xs hover:bg-transparent w-full text-center;
|
||||
}
|
||||
|
||||
.withdraw-button {
|
||||
opacity: v-bind(withdrawButtonOpacity);
|
||||
cursor: v-bind(withdrawButtonCursor);
|
||||
|
@ -7,4 +7,5 @@ export type WalletTransaction = {
|
||||
event: string;
|
||||
lockStatus: number;
|
||||
transactionHash: string;
|
||||
transactionID?: string;
|
||||
};
|
||||
|
@ -11,6 +11,12 @@ const router = createRouter({
|
||||
path: "/",
|
||||
name: "home",
|
||||
component: HomeView,
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "/:lockID",
|
||||
name: "redirect buy",
|
||||
component: HomeView,
|
||||
},
|
||||
{
|
||||
path: "/seller",
|
||||
|
@ -5,13 +5,13 @@ import BuyConfirmedComponent from "@/components/BuyConfirmedComponent/BuyConfirm
|
||||
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 { updateWalletStatus, checkUnreleasedLock } from "@/blockchain/wallet";
|
||||
import { getNetworksLiquidity } from "@/blockchain/events";
|
||||
import type { ValidDeposit } from "@/model/ValidDeposit";
|
||||
import router from "@/router";
|
||||
import { getUnreleasedLockById } from "@/blockchain/events";
|
||||
import CustomAlert from "@/components/CustomAlert/CustomAlert.vue";
|
||||
|
||||
enum Step {
|
||||
Search,
|
||||
@ -30,6 +30,8 @@ const tokenAmount = ref<number>();
|
||||
const lockID = ref<string>("");
|
||||
const loadingRelease = ref<boolean>(false);
|
||||
const showModal = ref<boolean>(false);
|
||||
const showBuyAlert = ref<boolean>(false);
|
||||
const paramLockID = window.history.state?.lockID;
|
||||
|
||||
const confirmBuyClick = async (
|
||||
selectedDeposit: ValidDeposit,
|
||||
@ -59,6 +61,7 @@ const confirmBuyClick = async (
|
||||
|
||||
const releaseTransaction = async (e2eId: string) => {
|
||||
flowStep.value = Step.List;
|
||||
showBuyAlert.value = true;
|
||||
loadingRelease.value = true;
|
||||
|
||||
if (lockID.value && tokenAmount.value && pixTarget.value) {
|
||||
@ -88,17 +91,30 @@ const checkForUnreleasedLocks = async (): Promise<void> => {
|
||||
}
|
||||
};
|
||||
|
||||
watch(walletAddress, async () => {
|
||||
await checkForUnreleasedLocks();
|
||||
});
|
||||
if (paramLockID) {
|
||||
const lockToRedirect = await getUnreleasedLockById(paramLockID as string);
|
||||
if (lockToRedirect) {
|
||||
lockID.value = lockToRedirect.lockID;
|
||||
tokenAmount.value = lockToRedirect.pix.value;
|
||||
pixTarget.value = Number(lockToRedirect.pix.pixKey);
|
||||
flowStep.value = Step.Buy;
|
||||
} else {
|
||||
flowStep.value = Step.Search;
|
||||
}
|
||||
} else {
|
||||
watch(walletAddress, async () => {
|
||||
await checkForUnreleasedLocks();
|
||||
});
|
||||
|
||||
watch(networkName, async () => {
|
||||
if (walletAddress.value) await checkForUnreleasedLocks();
|
||||
});
|
||||
watch(networkName, async () => {
|
||||
if (walletAddress.value) await checkForUnreleasedLocks();
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getNetworksLiquidity();
|
||||
if (walletAddress.value) await checkForUnreleasedLocks();
|
||||
if (walletAddress.value && !paramLockID) await checkForUnreleasedLocks();
|
||||
window.history.state.lockID = "";
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -107,12 +123,19 @@ onMounted(async () => {
|
||||
v-if="flowStep == Step.Search"
|
||||
@token-buy="confirmBuyClick"
|
||||
/>
|
||||
<CustomModal
|
||||
<CustomAlert
|
||||
v-if="flowStep == Step.Search && showModal"
|
||||
:isRedirectModal="true"
|
||||
@close-modal="showModal = false"
|
||||
:type="'redirect'"
|
||||
@close-alert="showModal = false"
|
||||
@go-to-lock="flowStep = Step.Buy"
|
||||
/>
|
||||
<CustomAlert
|
||||
v-if="
|
||||
flowStep == Step.List && showBuyAlert && !loadingLock && !loadingRelease
|
||||
"
|
||||
:type="'buy'"
|
||||
@close-alert="showBuyAlert = false"
|
||||
/>
|
||||
<div v-if="flowStep == Step.Buy">
|
||||
<QrCodeComponent
|
||||
:pixTarget="String(pixTarget)"
|
||||
|
@ -3,6 +3,7 @@ import { useEtherStore } from "@/store/ether";
|
||||
import { storeToRefs } from "pinia";
|
||||
import ListingComponent from "@/components/ListingComponent/ListingComponent.vue";
|
||||
import LoadingComponent from "@/components/LoadingComponent/LoadingComponent.vue";
|
||||
import CustomAlert from "@/components/CustomAlert/CustomAlert.vue";
|
||||
import { ref, watch, onMounted } from "vue";
|
||||
import {
|
||||
listValidDepositTransactionsByWalletAddress,
|
||||
@ -19,6 +20,7 @@ const etherStore = useEtherStore();
|
||||
|
||||
const { walletAddress, networkName } = storeToRefs(etherStore);
|
||||
const loadingWithdraw = ref<boolean>(false);
|
||||
const showAlert = ref<boolean>(false);
|
||||
|
||||
const depositList = ref<ValidDeposit[]>([]);
|
||||
const transactionsList = ref<WalletTransaction[]>([]);
|
||||
@ -37,6 +39,7 @@ const callWithdraw = async (amount: string) => {
|
||||
if (withdraw) {
|
||||
console.log("Saque realizado!");
|
||||
await getWalletTransactions();
|
||||
showAlert.value = true;
|
||||
} else {
|
||||
console.log("Não foi possível realizar o saque!");
|
||||
}
|
||||
@ -84,6 +87,11 @@ watch(networkName, async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CustomAlert
|
||||
v-if="showAlert"
|
||||
:type="'withdraw'"
|
||||
@close-alert="showAlert = false"
|
||||
/>
|
||||
<div class="page">
|
||||
<div class="header" v-if="!loadingWithdraw && !walletAddress">
|
||||
Por Favor Conecte Sua Carteira
|
||||
|
@ -6,6 +6,7 @@ import { approveTokens, addDeposit } from "@/blockchain/sellerMethods";
|
||||
|
||||
import { ref } from "vue";
|
||||
import { useEtherStore } from "@/store/ether";
|
||||
import CustomAlert from "@/components/CustomAlert/CustomAlert.vue";
|
||||
|
||||
enum Step {
|
||||
Search,
|
||||
@ -21,6 +22,7 @@ const loading = ref<boolean>(false);
|
||||
|
||||
const offerValue = ref<string>("");
|
||||
const pixKeyBuyer = ref<string>("");
|
||||
const showAlert = ref<boolean>(false);
|
||||
|
||||
// Verificar tipagem
|
||||
const approveOffer = async (args: {
|
||||
@ -48,6 +50,7 @@ const sendNetwork = async () => {
|
||||
await addDeposit(String(offerValue.value), pixKeyBuyer.value);
|
||||
flowStep.value = Step.Sell;
|
||||
loading.value = false;
|
||||
showAlert.value = true;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
@ -65,6 +68,11 @@ const sendNetwork = async () => {
|
||||
:message="'A transação está sendo enviada para a rede.'"
|
||||
/>
|
||||
</div>
|
||||
<CustomAlert
|
||||
v-if="flowStep == Step.Sell && showAlert"
|
||||
:type="'sell'"
|
||||
@close-alert="showAlert = false"
|
||||
/>
|
||||
<div v-if="flowStep == Step.Network">
|
||||
<SendNetwork
|
||||
:pixKey="pixKeyBuyer"
|
||||
|
Loading…
x
Reference in New Issue
Block a user