Merge pull request #60 from liftlearning/create_alerts

Create alerts
This commit is contained in:
Bruno Esteves 2023-02-28 21:35:58 -03:00 committed by GitHub
commit b9dd4a7621
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 292 additions and 36 deletions

View 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

View File

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

View File

@ -80,6 +80,9 @@ const filterLockStatus = async (
transactionHash: transaction.transactionHash
? transaction.transactionHash
: "",
transactionID: transaction.args?.lockID
? String(transaction.args?.lockID)
: "",
};
return tx;

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

View File

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

View File

@ -7,4 +7,5 @@ export type WalletTransaction = {
event: string;
lockStatus: number;
transactionHash: string;
transactionID?: string;
};

View File

@ -11,6 +11,12 @@ const router = createRouter({
path: "/",
name: "home",
component: HomeView,
props: true,
},
{
path: "/:lockID",
name: "redirect buy",
component: HomeView,
},
{
path: "/seller",

View File

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

View File

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

View File

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