Merge branch 'develop' into list-tokens

This commit is contained in:
RcleydsonR 2022-12-13 14:41:30 -03:00
commit d97093462b
18 changed files with 436 additions and 8172 deletions

1
.env.example Normal file
View File

@ -0,0 +1 @@
VITE_API_URL=http://localhost:8000/

2
.gitignore vendored
View File

@ -27,3 +27,5 @@ coverage
*.sln
*.sw?
.vercel
.env

7928
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@
"dependencies": {
"@headlessui/vue": "^1.7.3",
"@heroicons/vue": "^2.0.12",
"axios": "^1.2.1",
"crc": "^3.8.0",
"pinia": "^2.0.23",
"qrcode": "^1.5.1",

3
src/assets/copyPix.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="18" height="20" viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 3H3C1.89543 3 1 3.89543 1 5V17C1 18.1046 1.89543 19 3 19H13C14.1046 19 15 18.1046 15 17V16M5 3C5 4.10457 5.89543 5 7 5H9C10.1046 5 11 4.10457 11 3M5 3C5 1.89543 5.89543 1 7 1H9C10.1046 1 11 1.89543 11 3M11 3H13C14.1046 3 15 3.89543 15 5V8M17 12H7M7 12L10 9M7 12L10 15" stroke="#111827" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 467 B

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM4.18025 4.18034C4.42057 3.94001 4.81022 3.94001 5.05055 4.18034L8.00008 7.12987L10.9496 4.18034C11.1899 3.94001 11.5796 3.94001 11.8199 4.18034C12.0602 4.42067 12.0602 4.81031 11.8199 5.05064L8.87039 8.00018L11.8198 10.9495C12.0601 11.1899 12.0601 11.5795 11.8198 11.8198C11.5794 12.0602 11.1898 12.0602 10.9495 11.8198L8.00008 8.87048L5.05072 11.8198C4.81039 12.0602 4.42074 12.0602 4.18041 11.8198C3.94009 11.5795 3.94009 11.1899 4.18041 10.9495L7.12978 8.00018L4.18025 5.05064C3.93992 4.81031 3.93992 4.42067 4.18025 4.18034Z" fill="#EF4444"/>
</svg>

After

Width:  |  Height:  |  Size: 808 B

3
src/assets/validIcon.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 0C6.41775 0 4.87104 0.469192 3.55544 1.34824C2.23985 2.22729 1.21447 3.47672 0.608967 4.93853C0.00346629 6.40034 -0.15496 8.00887 0.153721 9.56072C0.462403 11.1126 1.22433 12.538 2.34315 13.6569C3.46197 14.7757 4.88743 15.5376 6.43928 15.8463C7.99113 16.155 9.59966 15.9965 11.0615 15.391C12.5233 14.7855 13.7727 13.7602 14.6518 12.4446C15.5308 11.129 16 9.58225 16 8C15.9975 5.87903 15.1539 3.84563 13.6541 2.34587C12.1544 0.846118 10.121 0.00247015 8 0V0ZM12.618 5.46667L8.05467 11.6593C8.0008 11.7308 7.93322 11.7908 7.85589 11.8359C7.77856 11.881 7.69303 11.9102 7.60429 11.9219C7.51554 11.9336 7.42536 11.9274 7.339 11.9039C7.25265 11.8803 7.17186 11.8398 7.10134 11.7847L3.84267 9.17933C3.7743 9.12462 3.71737 9.05697 3.67514 8.98025C3.63291 8.90353 3.6062 8.81924 3.59654 8.73221C3.57704 8.55642 3.62816 8.38009 3.73867 8.242C3.84918 8.10391 4.01001 8.01538 4.1858 7.99587C4.36158 7.97637 4.53791 8.02749 4.676 8.138L7.39334 10.312L11.5447 4.678C11.5946 4.603 11.6593 4.53892 11.7348 4.48962C11.8102 4.44032 11.8948 4.40683 11.9836 4.39117C12.0724 4.37551 12.1634 4.37801 12.2511 4.39851C12.3389 4.41902 12.4216 4.4571 12.4942 4.51047C12.5668 4.56383 12.6279 4.63136 12.6737 4.70899C12.7194 4.78661 12.749 4.87271 12.7606 4.96209C12.7722 5.05146 12.7655 5.14226 12.741 5.22898C12.7165 5.31571 12.6746 5.39656 12.618 5.46667Z" fill="#10B981"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

15
src/assets/validating.svg Normal file
View File

@ -0,0 +1,15 @@
<svg width="128" height="83" viewBox="0 0 128 83" fill="white" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_354_816)">
<path d="M61.0484 25.8089C60.6304 25.3649 60.0296 25.1298 59.4288 25.1298C58.828 25.1298 58.2272 25.3649 57.8092 25.8089L53.2378 30.3804C52.7937 30.7983 52.5586 31.3991 52.5586 32C52.5586 32.6008 52.7937 33.2016 53.2378 33.6196L57.8092 38.191C58.6974 39.0791 60.1602 39.0791 61.0484 38.191C61.9366 37.3028 61.9366 35.84 61.0484 34.9518L58.0704 32L61.0484 29.0481C61.4925 28.6302 61.7276 28.0294 61.7276 27.4285C61.7276 26.8277 61.4925 26.2269 61.0484 25.8089Z" fill="#34D399"/>
<path d="M79.334 25.8089C78.4459 24.9208 76.983 24.9208 76.0948 25.8089C75.2067 26.6971 75.2067 28.16 76.0948 29.0481L79.0728 32L76.0948 34.9518C75.2067 35.84 75.2067 37.3028 76.0948 38.191C76.983 39.0791 78.4459 39.0791 79.334 38.191L83.9055 33.6196C84.3495 33.2016 84.5846 32.6008 84.5846 32C84.5846 31.3991 84.3495 30.7983 83.9055 30.3804L79.334 25.8089Z" fill="#34D399"/>
<path d="M68.5714 41.6914L73.1428 23.4057C73.4563 22.1518 72.6726 20.8718 71.4188 20.5584C70.1649 20.2449 68.8849 21.0286 68.5714 22.2825L64 40.5682C63.8171 41.169 63.8955 41.7959 64.209 42.3445C64.5224 42.8931 65.0449 43.2588 65.6457 43.4155C66.2465 43.5723 66.8996 43.4678 67.422 43.1282C67.9445 42.7886 68.3102 42.2661 68.4408 41.6653L68.5714 41.6914Z" fill="#34D399"/>
<path d="M59.4288 48.0131H54.8574C53.6035 48.0131 52.5586 49.0318 52.5586 50.3118C52.5586 51.5918 53.5774 52.6106 54.8574 52.6106H59.4288C60.6827 52.6106 61.7276 51.5918 61.7276 50.3118C61.7276 49.0318 60.6827 48.0131 59.4288 48.0131Z" fill="#34D399"/>
<path d="M82.2855 48.0131H68.5712C67.3174 48.0131 66.2725 49.0318 66.2725 50.3118C66.2725 51.5918 67.2912 52.6106 68.5712 52.6106H82.2855C83.5394 52.6106 84.5843 51.5918 84.5843 50.3118C84.5843 49.0318 83.5394 48.0131 82.2855 48.0131Z" fill="#34D399"/>
<path d="M126.563 32.1567L115.122 27.5853C114.573 27.3763 113.972 27.3763 113.424 27.5853L101.982 32.1567C101.12 32.4963 100.545 33.3584 100.545 34.2727V38.8441H93.7012V13.7143C93.7012 13.1135 93.4661 12.5388 93.022 12.0947C92.578 11.6506 92.0033 11.4155 91.4024 11.4155H45.7143C44.4604 11.4155 43.4155 12.4343 43.4155 13.7143V38.8702H36.5714V13.7143C36.5714 13.1135 36.3363 12.5388 35.8922 12.0947C35.4482 11.6506 34.8735 11.4155 34.2727 11.4155H27.4286V6.8702C27.4286 5.9298 26.8539 5.09388 25.9918 4.75429L14.5502 0.156735C14.0016 -0.0522449 13.4008 -0.0522449 12.8522 0.156735L1.43673 4.72816C0.574694 5.06775 0 5.9298 0 6.8702V20.5845C0 21.5249 0.574694 22.3608 1.43673 22.7004L12.8784 27.2718C13.4269 27.4808 14.0278 27.4808 14.5763 27.2718L26.018 22.7004C26.88 22.3608 27.4547 21.4988 27.4547 20.5845V16.0131H32.0261V66.2988H27.4286V61.7273C27.4286 60.7869 26.8539 59.951 25.9918 59.6114L14.5502 55.04C14.0016 54.831 13.4008 54.831 12.8522 55.04L1.43673 59.5853C0.574694 59.9249 0 60.7869 0 61.7012V75.4155C0 76.3559 0.574694 77.1918 1.43673 77.5314L12.8784 82.1029C13.4269 82.3118 14.0278 82.3118 14.5763 82.1029L26.018 77.5314C26.88 77.1918 27.4547 76.3298 27.4547 75.4155V70.8441H34.2988C34.8996 70.8441 35.4743 70.609 35.9184 70.1649C36.3624 69.7208 36.5975 69.1461 36.5975 68.5453V43.4155H43.4416V64C43.4416 65.8286 44.1731 67.5527 45.4531 68.8588C46.7331 70.1649 48.4833 70.8702 50.3118 70.8702H91.4286C93.2571 70.8702 94.9812 70.1388 96.2873 68.8588C97.5935 67.5788 98.2988 65.8286 98.2988 64V59.4286C98.2988 58.8278 98.0637 58.2531 97.6196 57.809C97.1755 57.3649 96.6008 57.1298 96 57.1298H93.7012V43.4155H100.571V47.9869C100.571 48.9273 101.146 49.7633 102.008 50.1029L113.45 54.6743C113.998 54.8833 114.599 54.8833 115.148 54.6743L126.589 50.1029C127.451 49.7633 128.026 48.9012 128.026 47.9869V34.2727C128 33.3584 127.425 32.4963 126.563 32.1567ZM11.4155 21.76L4.57143 19.0171V10.24L11.4155 12.9829V21.76ZM13.7143 8.96L8.43755 6.84408L13.7143 4.72816L18.991 6.84408L13.7143 8.96ZM22.8571 19.0171L15.9869 21.76V12.9829L22.8571 10.24V19.0171ZM11.4155 76.6171L4.57143 73.8743V65.0971L11.4155 67.84V76.6171ZM13.7143 63.8171L8.43755 61.7012L13.7143 59.5853L18.991 61.7012L13.7143 63.8171ZM22.8571 73.8743L15.9869 76.6171V67.84L22.8571 65.0971V73.8743ZM93.7012 64C93.7012 64.6008 93.4661 65.1755 93.022 65.6196C92.578 66.0637 92.0033 66.2988 91.4024 66.2988H56.738C56.9992 65.5673 57.1559 64.7837 57.1559 64V61.7012H93.7273L93.7012 64ZM54.8571 57.1559C53.6033 57.1559 52.5584 58.1747 52.5584 59.4547V64C52.5584 65.2539 51.5396 66.2988 50.2596 66.2988C48.9796 66.2988 47.9608 65.28 47.9608 64V16.0131H89.1037V57.1559H54.8571ZM111.987 49.1886L105.143 46.4457V37.6686L111.987 40.4114V49.1886ZM114.286 36.3886L109.009 34.2727L114.286 32.1567L119.562 34.2727L114.286 36.3886ZM123.429 46.4457L116.584 49.1886V40.4114L123.429 37.6686V46.4457Z" fill="#34D399"/>
</g>
<defs>
<clipPath id="clip0_354_816">
<rect width="128" height="82.2857" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,210 @@
<script setup lang="ts">
import { pix } from "../utils/QrCodePix";
import { ref } from "vue";
import { debounce } from "@/utils/debounce";
import CustomButton from "./CustomButton.vue";
import api from "../services/index";
const props = defineProps({
pixTarget: String,
tokenValue: Number,
});
const qrCode = ref<string>("");
const qrCodePayload = ref<string>("");
const pixQrCode = pix({
pixKey: props.pixTarget ?? "",
value: props.tokenValue,
});
const isPixValid = ref<boolean>(false);
const isCodeInputEmpty = ref<boolean>(true);
pixQrCode.base64QrCode().then((code: string) => {
qrCode.value = code;
});
qrCodePayload.value = pixQrCode.payload();
const handleInputEvent = (event: any) => {
const { value } = event.target;
validatePix(value);
};
const validatePix = async (e2eid: any) => {
if (e2eid == "") {
isPixValid.value = false;
isCodeInputEmpty.value = true;
return;
}
var sellerPixKey = props.pixTarget;
var transactionValue = props.tokenValue;
if (sellerPixKey && transactionValue) {
var body_req = {
e2e_id: e2eid,
pix_key: sellerPixKey,
pix_value: transactionValue,
};
isCodeInputEmpty.value = false;
try {
await api.post("validate_pix", body_req);
isPixValid.value = true;
} catch (error) {
isPixValid.value = false;
}
} else {
isCodeInputEmpty.value = false;
isPixValid.value = false;
}
};
</script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-extrabold text-2xl max-w-[30rem]">
Utilize o QR Code ou copie o código para realizar o Pix
</span>
<span class="text font-medium text-md max-w-[28rem]">
Após realizar o Pix no banco de sua preferência, insira o código de
autenticação para enviar a transação para a rede.
</span>
</div>
<div class="blur-container max-w-[28rem] text-black">
<div
class="flex-col items-center justify-center flex w-full bg-white p-8 rounded-lg break-normal"
>
<img :src="qrCode" class="w-48 h-48" />
<span class="text-center font-bold">Código pix</span>
<div class="break-words w-4/5">
<span class="text-center text-xs">
{{ qrCodePayload }}
</span>
</div>
<img
alt="Copy PIX code"
src="@/assets/copyPix.svg"
width="16"
height="16"
class="pt-2 mb-5 cursor-pointer"
/>
<span class="text-xs text-start">
<strong>ATENÇÃO!</strong> A transação será processada após inserir
o código de autenticação. Caso contrário não conseguiremos comprovar o
seu depósito e não será possível transferir os tokens para sua
carteira. Confira aqui como encontrar o código no comprovante.
</span>
</div>
<div
class="flex-col items-center justify-center flex w-full bg-white p-5 rounded-lg px-5"
>
<input
type="text"
placeholder="Digite o código do comprovante PIX"
@input="debounce(handleInputEvent, 500)($event)"
class="text-md w-full box-border p-2 h-6 mb-2 outline-none"
/>
<div class="custom-divide" v-if="!isCodeInputEmpty"></div>
<div
class="flex flex-col w-full"
v-if="!isPixValid && !isCodeInputEmpty"
>
<div class="flex items-center h-8">
<img
alt="Invalid Icon"
src="@/assets/invalidIcon.svg"
width="14"
class="cursor-pointer align-middle inline-block"
/>
<span class="px-1 text-red-500 font-normal text-xs"
>Código inválido. Por favor, confira e tente novamente.</span
>
</div>
</div>
<div class="flex flex-col w-full" v-else-if="isPixValid == true">
<div class="flex items-center h-8">
<img
alt="Valid Icon"
src="@/assets/validIcon.svg"
width="14"
class="cursor-pointer align-middle inline-block"
/>
<span class="px-1 text-green-500 font-normal text-sm">
Código válido.
</span>
</div>
</div>
</div>
<CustomButton
:is-disabled="isPixValid == false"
:text="'Enviar para a rede'"
/>
</div>
</div>
</template>
<style scoped>
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
::placeholder {
/* Most modern browsers support this now. */
color: #9ca3af;
}
h4 {
color: #080808;
font-size: 14px;
}
h2 {
color: #080808;
}
.form-input {
@apply rounded-lg border border-gray-200 p-2 text-black;
}
.form-label {
@apply font-semibold tracking-wide text-emerald-50;
}
.custom-divide {
width: 100%;
border-bottom: 1px solid #d1d5db;
}
.bottom-position {
top: -20px;
right: 50%;
transform: translateX(50%);
}
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
.text-container {
@apply flex flex-col items-center justify-center gap-4;
}
.text {
@apply text-gray-800 text-center;
}
.blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-6;
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}
</style>

View File

@ -56,7 +56,6 @@ const decimalCount = (num: Number) => {
const verifyLiquidity = () => {
enableSelectButton.value = false;
selectedDeposit.value = null;
if (!walletAddress.value || tokenValue.value <= 0) return;
depositsAddedList.value.find((element) => {
@ -69,10 +68,6 @@ const verifyLiquidity = () => {
enableSelectButton.value = true;
hasLiquidity.value = true;
selectedDeposit.value = element;
console.log(
"Selected is :",
blockchain.formatBigNumber(element.args.amount)
);
return true;
}
return false;

View File

@ -0,0 +1,66 @@
<script setup lang="ts"></script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-bold text-3xl max-w-[29rem]"
>Confirme em sua carteira</span
>
</div>
<div class="blur-container w-[26rem]">
<div
class="flex flex-col w-full bg-white px-10 py-5 rounded-lg border-y-10"
>
<div
class="flex flex-col text-center justify-center w-full items-center p-2 px-3 rounded-3xl min-w-fit gap-1"
>
<img
alt="Polygon image"
src="@/assets/validating.svg"
width="96"
height="48"
/>
<span class="text-black font-medium text-sm px-12 mt-4">
A transação está sendo enviada para a rede
</span>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.custom-divide {
width: 100%;
border-bottom: 1px solid #d1d5db;
}
.bottom-position {
top: -20px;
right: 50%;
transform: translateX(50%);
}
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
.text-container {
@apply flex flex-col items-center justify-center gap-4;
}
.text {
@apply text-gray-800 text-center;
}
.blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-10;
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}
</style>

View File

@ -1,6 +1,5 @@
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";
import QrCodeFormVue from "../views/QrCodeForm.vue";
import MockView from "../views/MockView.vue";
import ListView from "../components/ListComponent.vue";
@ -12,11 +11,6 @@ const router = createRouter({
name: "home",
component: HomeView,
},
{
path: "/pix",
name: "pix",
component: QrCodeFormVue,
},
{
path: "/mock",
name: "mock",

14
src/services/index.ts Normal file
View File

@ -0,0 +1,14 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import axios from "axios";
const defaultConfig = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
};
const api = axios.create({
...defaultConfig,
baseURL: import.meta.env.VITE_API_URL,
});
export default api;

View File

@ -4,7 +4,7 @@ export const useEtherStore = defineStore("ether", {
state: () => ({
walletAddress: "",
balance: "",
loadingLock: false,
// Depósitos válidos para compra
depositsValidList: [] as any[],
// Depósitos adicionados na blockchain
@ -25,6 +25,9 @@ export const useEtherStore = defineStore("ether", {
setBalance(balance: string) {
this.balance = balance;
},
setLoadingLock(isLoadingLock: boolean) {
this.loadingLock = isLoadingLock;
},
setDepositsValidList(depositsValidList: any[]) {
this.depositsValidList = depositsValidList;
},

View File

@ -69,7 +69,7 @@ const generatePixKey = (pixKey: string, message?: string): string => {
};
const formatEMV = (id: string, param: string): string => {
const len = param.length.toString().padStart(2, "0");
const len = param?.length?.toString().padStart(2, "0");
return `${id}${len}${param}`;
};

View File

@ -1,46 +1,85 @@
<script setup lang="ts">
import SearchComponent from "../components/SearchComponent.vue";
import ValidationComponent from "../components/ValidationComponent.vue";
import blockchain from "../utils/blockchain";
import ListComponent from "@/components/ListComponent.vue";
import { ref } from "vue";
// (TO DO) Tirar isso tudo daqui
import p2pix from "../utils/smart_contract_files/P2PIX.json";
import addresses from "../utils/smart_contract_files/localhost.json";
import { useEtherStore } from "@/store/ether";
import { ethers } from "ethers";
import QrCodeComponent from "../components/QrCodeComponent.vue";
import { storeToRefs } from "pinia";
enum Step {
Search,
Buy,
List
}
const flowStep = ref<Step>(Step.Search)
const tokenAmmount = ref()
// States
const etherStore = useEtherStore();
const { loadingLock } = storeToRefs(etherStore);
const flowStep = ref<Step>(Step.Search);
const pixTarget = ref<string>("");
const tokens = ref<number>();
const confirmBuyClick = async ({ selectedDeposit, tokenValue }: any) => {
// finish buy screen
console.log(selectedDeposit);
let depositDetail;
const depositId = selectedDeposit["args"]["depositID"];
await blockchain
.mapDeposits(selectedDeposit.args.depositID)
.mapDeposits(depositId)
.then((deposit) => (depositDetail = deposit));
console.log(tokenValue);
tokenAmmount.value = tokenValue
flowStep.value = Step.List
tokens.value = tokenValue;
pixTarget.value = depositDetail?.pixTarget;
// Makes lock with deposit ID and the Amount
if (depositDetail) {
const lock = await blockchain.addLock(
selectedDeposit.args.depositID,
tokenValue
);
console.log(lock);
};
flowStep.value = Step.Buy;
etherStore.setLoadingLock(true);
};
await blockchain.addLock(depositId, tokenValue).catch(() => {
flowStep.value = Step.Search;
});
// (TO DO) Tirar isso daqui
const window_ = window as any;
const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null;
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterLocks = p2pContract.filters.LockAdded(null);
const eventsLocks = await p2pContract.queryFilter(filterLocks);
etherStore.setLocksAddedList(eventsLocks);
etherStore.setLoadingLock(false);
// Data to QRCode
// Chave Pix = depositDetail.pixTarget
// Valor = tokenValue
}
};
</script>
<template>
<SearchComponent v-if="(flowStep == Step.Search)" @token-buy="confirmBuyClick" />
<SearchComponent
v-if="flowStep == Step.Search"
@token-buy="confirmBuyClick"
/>
<div v-if="flowStep == Step.Buy">
<QrCodeComponent
:pixTarget="pixTarget"
:tokenValue="tokens"
v-if="!loadingLock"
/>
<ValidationComponent v-if="loadingLock" />
</div>
<Suspense>
<ListComponent v-if="(flowStep == Step.List)" :tokenAmmount="tokenAmmount" />
<ListComponent v-if="(flowStep == Step.List)" :tokenAmmount="tokens" />
<template #fallback>
Carregando...
</template>

View File

@ -1,214 +0,0 @@
<script setup lang="ts">
import { pix } from "../utils/QrCodePix";
import { ref } from "vue";
const pixModel = ref({
pixKey: "",
name: "",
city: "",
transactionId: "",
value: 0,
message: "",
qrCodePayload: "",
});
const qrCode = ref<string>("");
const qrCodePayload = ref<string>("");
const toggleModal = ref<boolean>(false);
const errors = ref({
pixRequiredError: false,
nameRequiredError: false,
cityRequiredError: false,
});
const submit = () => {
errors.value["pixRequiredError"] = pixModel.value["pixKey"] == "";
if (errors.value["pixRequiredError"]) return;
const pixQrCode = pix({
pixKey: pixModel.value.pixKey,
merchantName: pixModel.value.name.trim() ? pixModel.value.name : "name",
merchantCity: pixModel.value.city.trim() ? pixModel.value.city : "city",
transactionId: pixModel.value.transactionId.trim()
? pixModel.value.transactionId
: "***",
message: pixModel.value.message,
value: pixModel.value["value"],
});
pixQrCode.base64QrCode().then((code: string) => {
qrCode.value = code;
});
qrCodePayload.value = pixQrCode.payload();
toggleModal.value = true;
};
</script>
<template>
<div class="page">
<div class="form-container">
<h2 class="text-center font-bold text-emerald-50 text-2xl">
pixModel QR Code
</h2>
<form>
<div class="grid gap-4 grid-cols-1 p-2">
<div class="col-div">
<div class="mb-2">
<label for="pixKey" class="form-label">Chave PIX</label>
<span v-if="errors['pixRequiredError']" class="required-error"
>(Esse campo é obrigatório)</span
>
</div>
<input
type="text"
name="pixKey"
id="pixKey"
class="form-input"
v-model="pixModel.pixKey"
/>
</div>
<div class="col-div">
<div class="mb-2">
<label for="name" class="form-label">Nome do beneficiário</label>
<span v-if="errors['nameRequiredError']" class="required-error"
>(Esse campo é obrigatório)</span
>
</div>
<input
type="text"
name="name"
id="name"
class="form-input"
v-model="pixModel.name"
/>
</div>
<div class="col-div">
<div class="mb-2">
<label for="city" class="form-label"
>Cidade do beneficiário</label
>
<span v-if="errors['cityRequiredError']" class="required-error"
>(Esse campo é obrigatório)</span
>
</div>
<input
type="text"
name="city"
id="city"
class="form-input"
v-model="pixModel.city"
/>
</div>
<div class="col-div">
<label for="value" class="form-label"
>Valor de transferência (Opcional)</label
>
<input
type="number"
name="value"
id="value"
class="form-input"
v-model="pixModel.value"
/>
</div>
<div class="col-div">
<label for="code" class="form-label"
>Código da transferência (Opcional)</label
>
<input
type="text"
name="code"
id="code"
class="form-input"
v-model="pixModel.transactionId"
/>
</div>
<div class="col-div">
<label for="message" class="form-label">Mensagem (Opcional)</label>
<input
type="text"
name="message"
id="message"
class="form-input"
v-model="pixModel.message"
/>
</div>
<button type="button" class="button" @click="submit">
Gerar QR code
</button>
</div>
</form>
</div>
</div>
<div
v-if="toggleModal"
class="fixed overflow-x-hidden overflow-y-auto inset-0 flex justify-center items-center z-50"
>
<div class="relative mx-auto w-auto max-w-2xl">
<div
class="bg-white w-[500px] p-2 rounded shadow-2xl flex flex-col justify-center items-center gap-2"
>
<img v-if="qrCode != ''" :src="qrCode" alt="QR code image" />
<div>
<span class="text-black font-semibold mr-1">Chave pix:</span>
<span class="text-gray-700">{{ pixModel.pixKey }}</span>
</div>
<div v-if="pixModel.name.trim() != ''">
<span class="text-black font-semibold mr-1"
>Nome do Beneficiário:</span
>
<span class="text-gray-700">{{ pixModel.name }}</span>
</div>
<div v-if="pixModel.value != 0">
<span class="text-black font-semibold mr-1"
>Valor da transferência:</span
>
<span class="text-gray-700">{{ pixModel.value }}</span>
</div>
<div class="flex flex-col w-auto break-all justify-center items-center">
<span class="text-black font-semibold mb-2">Código QR Code:</span>
<span class="text-gray-700">{{ qrCodePayload }}</span>
</div>
<button type="button" class="button" @click="toggleModal = false">
Fechar
</button>
</div>
</div>
</div>
<div v-if="toggleModal" class="fixed z-40 inset-0 opacity-25 bg-black"></div>
</template>
<style scoped>
.page {
@apply mt-8 w-full flex justify-center self-center;
}
.form-container {
background-color: var(--color-background-indigo);
@apply rounded-md w-full p-2 w-1/2;
}
.col-div {
@apply flex flex-col;
}
.form-input {
@apply rounded-lg border border-gray-200 p-2 text-black;
}
.form-label {
@apply font-semibold tracking-wide text-emerald-50;
}
.button {
@apply rounded-lg w-full border border-emerald-900 text-white py-2 bg-emerald-600 hover:bg-emerald-500;
}
.required-error {
@apply ml-2 text-red-500;
}
</style>

View File

@ -1125,6 +1125,11 @@ array-union@^2.1.0:
resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
autoprefixer@^10.4.12:
version "10.4.12"
resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz"
@ -1137,6 +1142,15 @@ autoprefixer@^10.4.12:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
axios@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.1.tgz#44cf04a3c9f0c2252ebd85975361c026cb9f864a"
integrity sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
@ -1315,6 +1329,13 @@ color-name@^1.1.4, color-name@~1.1.4:
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
@ -1397,6 +1418,11 @@ defined@^1.0.0:
resolved "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz"
integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
detective@^5.2.1:
version "5.2.1"
resolved "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz"
@ -1915,6 +1941,20 @@ flatted@^3.1.0:
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
fraction.js@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz"
@ -2407,6 +2447,18 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.2"
picomatch "^2.3.1"
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -2745,6 +2797,11 @@ prettier@^2.7.1:
resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz"
integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
punycode@^2.1.0:
version "2.1.1"
resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"