Added Sellet from with all required fields.
This commit is contained in:
parent
9cda680494
commit
92f6cb4d35
@ -19,3 +19,14 @@
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(15px);
|
transform: translateY(15px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.resize-enter-active,
|
||||||
|
.resize-leave-active {
|
||||||
|
max-height: 100px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-enter-from,
|
||||||
|
.resize-leave-to {
|
||||||
|
max-height: 0px;
|
||||||
|
}
|
||||||
|
360
src/components/SellerSteps/SellerComponent.vue
Normal file
360
src/components/SellerSteps/SellerComponent.vue
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
import CustomButton from "../CustomButton/CustomButton.vue";
|
||||||
|
import { pixFormatValidation, postProcessKey } from "@/utils/pixKeyFormat";
|
||||||
|
import { useEtherStore } from "@/store/ether";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import { TokenEnum } from "@/model/NetworkEnum";
|
||||||
|
import { getTokenImage } from "@/utils/imagesPath";
|
||||||
|
import { useOnboard } from "@web3-onboard/vue";
|
||||||
|
import ChevronDown from "@/assets/chevron.svg";
|
||||||
|
|
||||||
|
// Define Bank interface
|
||||||
|
interface Bank {
|
||||||
|
ISPB: string;
|
||||||
|
longName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// html references
|
||||||
|
const tokenDropdownRef = ref<any>(null);
|
||||||
|
const formRef = ref<HTMLFormElement | null>(null);
|
||||||
|
|
||||||
|
// Reactive state
|
||||||
|
const etherStore = useEtherStore();
|
||||||
|
const { walletAddress, selectedToken } = storeToRefs(etherStore);
|
||||||
|
|
||||||
|
const fullName = ref<string>("");
|
||||||
|
const offer = ref<string>("");
|
||||||
|
const identification = ref<string>("");
|
||||||
|
const account = ref<string>("");
|
||||||
|
const branch = ref<string>("");
|
||||||
|
const accountType = ref<string>("");
|
||||||
|
const selectTokenToggle = ref<boolean>(false);
|
||||||
|
const savingsVariation = ref<string>("");
|
||||||
|
const errors = ref<{ [key: string]: string }>({});
|
||||||
|
|
||||||
|
// Bank selection
|
||||||
|
const bankSearchQuery = ref<string>("");
|
||||||
|
const showBankList = ref<boolean>(false);
|
||||||
|
const selectedBank = ref<Bank | null>(null);
|
||||||
|
|
||||||
|
// Import the bank list
|
||||||
|
import bankList from "@/utils/files/isbpList.json";
|
||||||
|
|
||||||
|
const filteredBanks = computed(() => {
|
||||||
|
if (!bankSearchQuery.value) return [];
|
||||||
|
return bankList
|
||||||
|
.filter((bank) =>
|
||||||
|
bank.longName.toLowerCase().includes(bankSearchQuery.value.toLowerCase())
|
||||||
|
)
|
||||||
|
.slice(0, 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleBankSelect = (bank: Bank) => {
|
||||||
|
selectedBank.value = bank;
|
||||||
|
bankSearchQuery.value = bank.longName;
|
||||||
|
showBankList.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Emits
|
||||||
|
const emit = defineEmits(["approveTokens"]);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
const connectAccount = async (): Promise<void> => {
|
||||||
|
const { connectWallet } = useOnboard();
|
||||||
|
await connectWallet();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e: Event): void => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const processedIdentification = postProcessKey(identification.value);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
offer: offer.value,
|
||||||
|
fullName: fullName.value,
|
||||||
|
identification: processedIdentification,
|
||||||
|
bankIspb: selectedBank.value?.ISPB,
|
||||||
|
accountType: accountType.value,
|
||||||
|
account: account.value,
|
||||||
|
branch: branch.value,
|
||||||
|
|
||||||
|
savingsVariation: savingsVariation.value || "",
|
||||||
|
};
|
||||||
|
|
||||||
|
emit("approveTokens", data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Token selection
|
||||||
|
const openTokenSelection = (): void => {
|
||||||
|
selectTokenToggle.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectedToken = (token: TokenEnum): void => {
|
||||||
|
etherStore.setSelectedToken(token);
|
||||||
|
selectTokenToggle.value = false;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="page w-full">
|
||||||
|
<div class="text-container">
|
||||||
|
<span
|
||||||
|
class="text font-extrabold sm:text-5xl text-3xl sm:max-w-[29rem] max-w-[20rem]"
|
||||||
|
>
|
||||||
|
Venda cripto e receba em Pix
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="text font-medium sm:text-base text-xs sm:max-w-[28rem] max-w-[30rem] sm:tracking-normal tracking-wide"
|
||||||
|
>
|
||||||
|
Digite sua oferta, informe a chave Pix, selecione a rede, aprove o envio
|
||||||
|
da transação e confirme sua oferta.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form ref="formRef" @submit="handleSubmit" class="main-container">
|
||||||
|
<!-- Offer input -->
|
||||||
|
<div
|
||||||
|
class="flex justify-between items-center w-full bg-white sm:px-10 px-6 py-5 rounded-lg border-y-10 gap-4"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
v-model="offer"
|
||||||
|
class="border-none outline-none text-gray-900 sm:w-fit w-3/4 flex-grow"
|
||||||
|
:class="{
|
||||||
|
'!font-medium': offer !== undefined && offer !== '',
|
||||||
|
'text-xl': offer !== undefined && offer !== '',
|
||||||
|
}"
|
||||||
|
min="0.01"
|
||||||
|
max="999999999.99"
|
||||||
|
pattern="\d+(\.\d{0,2})?"
|
||||||
|
placeholder="Digite sua oferta (mínimo R$0,01)"
|
||||||
|
step=".01"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<div class="relative overflow-visible">
|
||||||
|
<button
|
||||||
|
ref="tokenDropdownRef"
|
||||||
|
class="flex flex-row items-center p-2 bg-gray-300 hover:bg-gray-200 focus:outline-indigo-800 focus:outline-2 rounded-3xl min-w-fit gap-2 transition-colors"
|
||||||
|
@click="openTokenSelection()"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Token image"
|
||||||
|
class="sm:w-fit w-4"
|
||||||
|
:src="getTokenImage(selectedToken)"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="text-gray-900 sm:text-lg text-md font-medium"
|
||||||
|
id="token"
|
||||||
|
>
|
||||||
|
{{ selectedToken }}
|
||||||
|
</span>
|
||||||
|
<ChevronDown
|
||||||
|
class="text-gray-900 pr-4 sm:pr-0 transition-all duration-500 ease-in-out"
|
||||||
|
:class="{ 'scale-y-[-1]': selectTokenToggle }"
|
||||||
|
alt="Chevron Down"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<transition name="dropdown">
|
||||||
|
<div
|
||||||
|
v-if="selectTokenToggle"
|
||||||
|
class="mt-2 text-gray-900 absolute right-0 z-50 w-full min-w-max"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bg-white rounded-xl z-10 border border-gray-300 drop-shadow-md shadow-md overflow-clip"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="token in TokenEnum"
|
||||||
|
:key="token"
|
||||||
|
class="flex menu-button gap-2 px-4 cursor-pointer hover:bg-gray-300 transition-colors"
|
||||||
|
@click="handleSelectedToken(token)"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:alt="token + ' logo'"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
:src="getTokenImage(token)"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="text-gray-900 py-4 text-end font-semibold text-sm"
|
||||||
|
>
|
||||||
|
{{ token }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Full name input -->
|
||||||
|
<div
|
||||||
|
class="flex flex-col w-full bg-white sm:px-10 px-6 py-4 rounded-lg border-y-10"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="fullName"
|
||||||
|
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-full"
|
||||||
|
maxlength="60"
|
||||||
|
:class="{ 'text-xl font-medium': fullName }"
|
||||||
|
placeholder="Digite seu nome completo"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- CPF or CNPJ input -->
|
||||||
|
<div
|
||||||
|
class="flex flex-col w-full bg-white sm:px-10 px-6 py-4 rounded-lg border-y-10"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="identification"
|
||||||
|
maxlength="14"
|
||||||
|
:pattern="'^\\d{11}$|^\\d{14}$'"
|
||||||
|
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-full"
|
||||||
|
:class="{ 'text-xl font-medium': identification }"
|
||||||
|
placeholder="Digite seu CPF ou CNPJ (somente números)"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- Bank selection -->
|
||||||
|
<div
|
||||||
|
class="flex flex-col w-full bg-white sm:px-10 px-6 py-4 rounded-lg border-y-10"
|
||||||
|
>
|
||||||
|
<div class="relative">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="bankSearchQuery"
|
||||||
|
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-full"
|
||||||
|
:class="{ 'text-xl font-medium': bankSearchQuery }"
|
||||||
|
placeholder="Buscar banco"
|
||||||
|
@focus="showBankList = true"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-if="showBankList && filteredBanks.length > 0"
|
||||||
|
class="absolute top-full left-0 right-0 mt-1 bg-white border border-gray-200 rounded-md shadow-lg z-50 max-h-60 overflow-y-auto"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="bank in filteredBanks"
|
||||||
|
:key="bank.ISPB"
|
||||||
|
class="px-4 py-2 hover:bg-gray-100 cursor-pointer transition-colors"
|
||||||
|
@click="handleBankSelect(bank)"
|
||||||
|
>
|
||||||
|
<div class="text-sm font-medium text-gray-900">
|
||||||
|
{{ bank.longName }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-500">ISPB: {{ bank.ISPB }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span v-if="errors.bank" class="text-red-500 text-sm mt-2">{{
|
||||||
|
errors.bank
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
<!-- Account and Branch inputs -->
|
||||||
|
<div
|
||||||
|
class="flex flex-col w-full bg-white sm:px-10 px-6 py-4 rounded-lg border-y-10"
|
||||||
|
>
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<div class="flex-1">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="account"
|
||||||
|
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-full"
|
||||||
|
:class="{ 'text-xl font-medium': account }"
|
||||||
|
placeholder="Número da conta"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="branch"
|
||||||
|
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-full"
|
||||||
|
:class="{ 'text-xl font-medium': branch }"
|
||||||
|
placeholder="Agência"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Account Type Selection -->
|
||||||
|
<div
|
||||||
|
class="flex flex-col w-full bg-white sm:px-10 px-6 py-4 rounded-lg border-y-10"
|
||||||
|
>
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<div class="flex-1">
|
||||||
|
<select
|
||||||
|
v-model="accountType"
|
||||||
|
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-full"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<option value="" disabled selected>Tipo de conta</option>
|
||||||
|
<option value="1">Conta Corrente</option>
|
||||||
|
<option value="2">Conta Poupança</option>
|
||||||
|
<option value="3">Conta Salário</option>
|
||||||
|
<option value="4">Conta Pré-Paga</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Savings Account Variation -->
|
||||||
|
<Transition name="resize">
|
||||||
|
<input
|
||||||
|
v-if="accountType === '2'"
|
||||||
|
type="text"
|
||||||
|
v-model="savingsVariation"
|
||||||
|
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-full bg-white sm:px-10 px-6 py-4 rounded-lg border-y-10"
|
||||||
|
:class="{ 'text-xl font-medium': savingsVariation }"
|
||||||
|
placeholder="Variação da poupança"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Transition>
|
||||||
|
<!-- Action buttons -->
|
||||||
|
<CustomButton v-if="walletAddress" type="submit" text="Aprovar tokens" />
|
||||||
|
<CustomButton
|
||||||
|
v-else
|
||||||
|
text="Conectar carteira"
|
||||||
|
@buttonClicked="connectAccount()"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</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-white text-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
appearance: textfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"]::-webkit-inner-spin-button,
|
||||||
|
input[type="number"]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
@apply sm:text-lg text-sm;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,263 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref } from "vue";
|
|
||||||
import CustomButton from "../CustomButton/CustomButton.vue";
|
|
||||||
import { debounce } from "@/utils/debounce";
|
|
||||||
import { decimalCount } from "@/utils/decimalCount";
|
|
||||||
import { pixFormatValidation, postProcessKey } from "@/utils/pixKeyFormat";
|
|
||||||
import { useEtherStore } from "@/store/ether";
|
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
import { connectProvider } from "@/blockchain/provider";
|
|
||||||
import { TokenEnum } from "@/model/NetworkEnum";
|
|
||||||
import { getTokenImage } from "@/utils/imagesPath";
|
|
||||||
import { onClickOutside } from "@vueuse/core";
|
|
||||||
import { useOnboard } from "@web3-onboard/vue";
|
|
||||||
|
|
||||||
import ChevronDown from "@/assets/chevron.svg";
|
|
||||||
|
|
||||||
// html references
|
|
||||||
const tokenDropdownRef = ref<any>(null);
|
|
||||||
|
|
||||||
// Reactive state
|
|
||||||
const etherStore = useEtherStore();
|
|
||||||
const { walletAddress, selectedToken } = storeToRefs(etherStore);
|
|
||||||
|
|
||||||
const offer = ref<string>("");
|
|
||||||
const pixKey = ref<string>("");
|
|
||||||
const selectTokenToggle = ref<boolean>(false);
|
|
||||||
|
|
||||||
const enableSelectButton = ref<boolean>(false);
|
|
||||||
const hasLiquidity = ref<boolean>(true);
|
|
||||||
const validDecimals = ref<boolean>(true);
|
|
||||||
const validPixFormat = ref<boolean>(true);
|
|
||||||
|
|
||||||
// Emits
|
|
||||||
const emit = defineEmits(["approveTokens"]);
|
|
||||||
|
|
||||||
// Blockchain methods
|
|
||||||
const connectAccount = async (): Promise<void> => {
|
|
||||||
const { connectWallet } = useOnboard();
|
|
||||||
await connectWallet();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Debounce methods
|
|
||||||
const handleInputEvent = (event: any): void => {
|
|
||||||
const { value } = event.target;
|
|
||||||
|
|
||||||
offer.value = value;
|
|
||||||
|
|
||||||
if (decimalCount(offer.value) > 2) {
|
|
||||||
validDecimals.value = false;
|
|
||||||
enableSelectButton.value = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
validDecimals.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePixKeyInputEvent = (event: any): void => {
|
|
||||||
const { value } = event.target;
|
|
||||||
|
|
||||||
pixKey.value = value;
|
|
||||||
|
|
||||||
if (pixFormatValidation(pixKey.value)) {
|
|
||||||
validPixFormat.value = true;
|
|
||||||
enableSelectButton.value = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enableSelectButton.value = false;
|
|
||||||
validPixFormat.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const openTokenSelection = (): void => {
|
|
||||||
selectTokenToggle.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
onClickOutside(tokenDropdownRef, () => {
|
|
||||||
selectTokenToggle.value = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleSelectedToken = (token: TokenEnum): void => {
|
|
||||||
etherStore.setSelectedToken(token);
|
|
||||||
selectTokenToggle.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSellClick = async (
|
|
||||||
offer: string,
|
|
||||||
pixKey: string
|
|
||||||
): Promise<void> => {
|
|
||||||
const postProcessedPixKey = postProcessKey(pixKey);
|
|
||||||
emit("approveTokens", { offer, postProcessedPixKey });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="page w-full">
|
|
||||||
<div class="text-container">
|
|
||||||
<span
|
|
||||||
class="text font-extrabold sm:text-5xl text-3xl sm:max-w-[29rem] max-w-[20rem]"
|
|
||||||
>Venda cripto e receba em Pix</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="text font-medium sm:text-base text-xs sm:max-w-[28rem] max-w-[30rem] sm:tracking-normal tracking-wide"
|
|
||||||
>Digite sua oferta, informe a chave Pix, selecione a rede, aprove o
|
|
||||||
envio da transação e confirme sua oferta.</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="main-container">
|
|
||||||
<div class="backdrop-blur -z-10 w-full h-full"></div>
|
|
||||||
<div
|
|
||||||
class="flex flex-col w-full bg-white sm:px-10 px-6 py-5 rounded-lg border-y-10"
|
|
||||||
>
|
|
||||||
<div class="flex justify-between items-center">
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
v-model="offer"
|
|
||||||
class="border-none outline-none text-gray-900 sm:w-fit w-3/4"
|
|
||||||
:class="{
|
|
||||||
'!font-medium': offer !== undefined && offer !== '',
|
|
||||||
'text-xl': offer !== undefined && offer !== '',
|
|
||||||
}"
|
|
||||||
@input="debounce(handleInputEvent, 500)($event)"
|
|
||||||
placeholder="Digite sua oferta"
|
|
||||||
step=".01"
|
|
||||||
/>
|
|
||||||
<div class="relative overflow-visible">
|
|
||||||
<button
|
|
||||||
ref="tokenDropdownRef"
|
|
||||||
class="flex flex-row items-center p-2 bg-gray-300 hover:bg-gray-200 focus:outline-indigo-800 focus:outline-2 rounded-3xl min-w-fit gap-2 transition-colors"
|
|
||||||
@click="openTokenSelection()"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="Token image"
|
|
||||||
class="sm:w-fit w-4"
|
|
||||||
:src="getTokenImage(selectedToken)"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="text-gray-900 sm:text-lg text-md font-medium"
|
|
||||||
id="token"
|
|
||||||
>
|
|
||||||
{{ selectedToken }}
|
|
||||||
</span>
|
|
||||||
<ChevronDown
|
|
||||||
class="text-gray-900 pr-4 sm:pr-0 transition-all duration-500 ease-in-out"
|
|
||||||
:class="{ 'scale-y-[-1]': selectTokenToggle }"
|
|
||||||
alt="Chevron Down"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<transition name="dropdown">
|
|
||||||
<div
|
|
||||||
v-if="selectTokenToggle"
|
|
||||||
class="mt-2 text-gray-900 absolute right-0 z-50 w-full min-w-max"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="bg-white rounded-xl z-10 border border-gray-300 drop-shadow-md shadow-md overflow-clip"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="token in TokenEnum"
|
|
||||||
:key="token"
|
|
||||||
class="flex menu-button gap-2 px-4 cursor-pointer hover:bg-gray-300 transition-colors"
|
|
||||||
@click="handleSelectedToken(token)"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:alt="token + ' logo'"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
:src="getTokenImage(token)"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="text-gray-900 py-4 text-end font-semibold text-sm"
|
|
||||||
>
|
|
||||||
{{ token }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex pt-2 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 pt-2 justify-center" v-else-if="!hasLiquidity">
|
|
||||||
<span class="text-red-500 font-normal text-sm"
|
|
||||||
>Atualmente não há liquidez nas redes para sua demanda</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex flex-col w-full bg-white sm:px-10 px-6 py-8 rounded-lg border-y-10"
|
|
||||||
>
|
|
||||||
<div class="flex justify-between w-full items-center">
|
|
||||||
<input
|
|
||||||
@input="debounce(handlePixKeyInputEvent, 500)($event)"
|
|
||||||
type="text"
|
|
||||||
v-model="pixKey"
|
|
||||||
class="border-none outline-none sm:text-lg text-sm text-gray-900 w-fit"
|
|
||||||
:class="{
|
|
||||||
'!font-medium': pixKey !== undefined && pixKey !== '',
|
|
||||||
'text-xl': pixKey !== undefined && pixKey !== '',
|
|
||||||
}"
|
|
||||||
placeholder="Digite a chave Pix"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex pt-2 justify-center" v-if="!validPixFormat">
|
|
||||||
<span class="text-red-500 font-normal text-sm"
|
|
||||||
>Por favor utilize telefone, CPF ou CNPJ</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<CustomButton
|
|
||||||
v-if="walletAddress"
|
|
||||||
:text="'Aprovar tokens'"
|
|
||||||
:isDisabled="!validDecimals || !validPixFormat"
|
|
||||||
@buttonClicked="handleSellClick(offer, pixKey)"
|
|
||||||
/>
|
|
||||||
<CustomButton
|
|
||||||
v-if="!walletAddress"
|
|
||||||
:text="'Conectar carteira'"
|
|
||||||
@buttonClicked="connectAccount()"
|
|
||||||
/>
|
|
||||||
</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-white text-center;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="number"] {
|
|
||||||
-moz-appearance: textfield;
|
|
||||||
appearance: textfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="number"]::-webkit-inner-spin-button,
|
|
||||||
input[type="number"]::-webkit-outer-spin-button {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
@apply sm:text-lg text-sm;
|
|
||||||
}
|
|
||||||
</style>
|
|
5
src/model/Bank.ts
Normal file
5
src/model/Bank.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface Bank {
|
||||||
|
COMPE: string;
|
||||||
|
ISPB: string;
|
||||||
|
longName: string;
|
||||||
|
}
|
2142
src/utils/files/isbpList.json
Normal file
2142
src/utils/files/isbpList.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import WantSellComponent from "@/components/SellerSteps/WantSellComponent.vue";
|
import SellerComponent from "@/components/SellerSteps/SellerComponent.vue";
|
||||||
import SendNetwork from "@/components/SellerSteps/SendNetwork.vue";
|
import SendNetwork from "@/components/SellerSteps/SendNetwork.vue";
|
||||||
import LoadingComponent from "@/components/LoadingComponent/LoadingComponent.vue";
|
import LoadingComponent from "@/components/LoadingComponent/LoadingComponent.vue";
|
||||||
import { approveTokens, addDeposit } from "@/blockchain/sellerMethods";
|
import { approveTokens, addDeposit } from "@/blockchain/sellerMethods";
|
||||||
@ -14,6 +14,15 @@ enum Step {
|
|||||||
Network,
|
Network,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SellerData {
|
||||||
|
identification: string;
|
||||||
|
account: string;
|
||||||
|
branch: string;
|
||||||
|
bankIspb: string;
|
||||||
|
accountType: string;
|
||||||
|
savingsVariation: string;
|
||||||
|
}
|
||||||
|
|
||||||
const etherStore = useEtherStore();
|
const etherStore = useEtherStore();
|
||||||
etherStore.setSellerView(true);
|
etherStore.setSellerView(true);
|
||||||
|
|
||||||
@ -21,7 +30,6 @@ const flowStep = ref<Step>(Step.Sell);
|
|||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
|
|
||||||
const offerValue = ref<string>("");
|
const offerValue = ref<string>("");
|
||||||
const pixKeyBuyer = ref<string>("");
|
|
||||||
const showAlert = ref<boolean>(false);
|
const showAlert = ref<boolean>(false);
|
||||||
|
|
||||||
// Verificar tipagem
|
// Verificar tipagem
|
||||||
@ -32,7 +40,6 @@ const approveOffer = async (args: {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
offerValue.value = args.offer;
|
offerValue.value = args.offer;
|
||||||
pixKeyBuyer.value = args.postProcessedPixKey;
|
|
||||||
await approveTokens(args.offer);
|
await approveTokens(args.offer);
|
||||||
flowStep.value = Step.Network;
|
flowStep.value = Step.Network;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@ -46,8 +53,8 @@ const approveOffer = async (args: {
|
|||||||
const sendNetwork = async () => {
|
const sendNetwork = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
if (offerValue.value && pixKeyBuyer.value) {
|
if (offerValue.value) {
|
||||||
await addDeposit(String(offerValue.value), pixKeyBuyer.value);
|
await addDeposit(String(offerValue.value));
|
||||||
flowStep.value = Step.Sell;
|
flowStep.value = Step.Sell;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
showAlert.value = true;
|
showAlert.value = true;
|
||||||
@ -63,7 +70,7 @@ const sendNetwork = async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="flowStep == Step.Sell">
|
<div v-if="flowStep == Step.Sell">
|
||||||
<WantSellComponent v-if="!loading" @approve-tokens="approveOffer" />
|
<SellerComponent v-if="!loading" @approve-tokens="approveOffer" />
|
||||||
<LoadingComponent
|
<LoadingComponent
|
||||||
v-if="loading"
|
v-if="loading"
|
||||||
:message="'A transação está sendo enviada para a rede.'"
|
:message="'A transação está sendo enviada para a rede.'"
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
"include": [
|
"include": [
|
||||||
"env.d.ts",
|
"env.d.ts",
|
||||||
"src/**/*",
|
"src/**/*",
|
||||||
"src/**/*.vue"
|
"src/**/*.vue",
|
||||||
|
"scripts"
|
||||||
],
|
],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
@ -10,6 +10,17 @@ export default defineConfig({
|
|||||||
build: {
|
build: {
|
||||||
target: "esnext",
|
target: "esnext",
|
||||||
},
|
},
|
||||||
|
optimizeDeps: {
|
||||||
|
esbuildOptions: {
|
||||||
|
target: "esnext",
|
||||||
|
define: {
|
||||||
|
global: "globalThis",
|
||||||
|
},
|
||||||
|
supported: {
|
||||||
|
bigint: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
test: {
|
test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
environment: "jsdom",
|
environment: "jsdom",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user