add default page layout with header

Co-authored-by: brunoedcf <brest.dallacosta@outlook.com>
This commit is contained in:
RcleydsonR 2022-11-21 16:02:01 -03:00
parent 328bb9ad62
commit 35a92b2ca8
21 changed files with 231 additions and 546 deletions

View File

@ -4,6 +4,8 @@ import TopBar from "./components/TopBar.vue";
<template> <template>
<TopBar /> <TopBar />
<RouterView/>
</template> </template>
<style scoped></style> <style scoped></style>

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

@ -0,0 +1,3 @@
<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="M5.5 0C4.67157 0 4 0.671573 4 1.5V3H5V1.5C5 1.22386 5.22386 1 5.5 1H12.5C12.7761 1 13 1.22386 13 1.5V8.5C13 8.77614 12.7761 9 12.5 9H5.5C5.22386 9 5 8.77614 5 8.5V7H4V8.5C4 9.32843 4.67157 10 5.5 10H12.5C13.3284 10 14 9.32843 14 8.5V1.5C14 0.671573 13.3284 0 12.5 0H5.5ZM9 12.5C9 12.7761 8.77614 13 8.5 13L1.5 13C1.22386 13 1 12.7761 1 12.5L1 5.5C1 5.22386 1.22386 5 1.5 5L8.5 5C8.77614 5 9 5.22386 9 5.5V8H10V5.5C10 4.67157 9.32843 4 8.5 4L1.5 4C0.671574 4 0 4.67157 0 5.5V12.5C0 13.3284 0.671573 14 1.5 14L8.5 14C9.32843 14 10 13.3284 10 12.5V12H9V12.5Z" fill="#F59E0B"/>
</svg>

After

Width:  |  Height:  |  Size: 726 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="M1.64645 4.64645C1.84171 4.45118 2.15829 4.45118 2.35355 4.64645L8 10.2929L13.6464 4.64645C13.8417 4.45118 14.1583 4.45118 14.3536 4.64645C14.5488 4.84171 14.5488 5.15829 14.3536 5.35355L8.35355 11.3536C8.15829 11.5488 7.84171 11.5488 7.64645 11.3536L1.64645 5.35355C1.45118 5.15829 1.45118 4.84171 1.64645 4.64645Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 484 B

4
src/assets/ethereum.svg Normal file
View File

@ -0,0 +1,4 @@
<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 16ZM8.16801 2.56435C8.09081 2.43177 7.89923 2.4319 7.82221 2.56458L4.82431 7.72899C4.76983 7.82284 4.80013 7.94301 4.89259 7.99981L7.89038 9.84139C7.95451 9.88079 8.03533 9.88085 8.09952 9.84154L11.1069 7.99986C11.1996 7.94308 11.23 7.82262 11.1752 7.72866L8.16801 2.56435ZM8.08754 10.7831C8.02182 10.8253 7.93759 10.8253 7.87181 10.7833L5.51555 9.27665C5.33379 9.16043 5.1222 9.37463 5.24065 9.55495L7.8123 13.4701C7.89136 13.5905 8.06789 13.5903 8.14678 13.4699L10.7098 9.55566C10.828 9.37517 10.6161 9.16127 10.4345 9.27775L8.08754 10.7831Z" fill="#3B82F6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.82232 2.56456C7.89934 2.43187 8.09092 2.43174 8.16812 2.56432L11.1754 7.72864C11.2301 7.8226 11.1997 7.94305 11.107 7.99984L8.09963 9.84152C8.03544 9.88082 7.95463 9.88077 7.89049 9.84137L4.8927 7.99979C4.80024 7.94299 4.76994 7.82282 4.82442 7.72897L7.82232 2.56456ZM7.87193 10.7833C7.9377 10.8253 8.02193 10.8253 8.08765 10.7831L10.4346 9.27773C10.6162 9.16125 10.8281 9.37515 10.7099 9.55563L8.1469 13.4698C8.06801 13.5903 7.89147 13.5904 7.81241 13.4701L5.24076 9.55492C5.12232 9.3746 5.3339 9.1604 5.51566 9.27662L7.87193 10.7833Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -6,10 +6,10 @@
#app { #app {
margin: 0 auto; margin: 0 auto;
padding: 2rem 4rem; padding: 2rem 4rem;
height: 100vh; height: fit-content;
min-height: 100vh;
background-image: url( './bg.svg' ); background-image: url( './bg.svg' );
background-size: cover; background-size: cover;
font-weight: normal; font-weight: normal;
} }
@ -25,6 +25,3 @@ a,
background-color: hsla(160, 100%, 37%, 0.2); background-color: hsla(160, 100%, 37%, 0.2);
} }
} }
@media (min-width: 1024px) {
}

View File

@ -1,41 +0,0 @@
<script setup lang="ts">
defineProps<{
msg: string;
}>();
</script>
<template>
<div class="greetings">
<h1 class="green">{{ msg }}</h1>
<h3>
Youve successfully created a project with
<a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
What's next?
</h3>
</div>
</template>
<style scoped>
h1 {
font-weight: 500;
font-size: 2.6rem;
top: -10px;
}
h3 {
font-size: 1.2rem;
}
.greetings h1,
.greetings h3 {
text-align: center;
}
@media (min-width: 1024px) {
.greetings h1,
.greetings h3 {
text-align: left;
}
}
</style>

View File

@ -1,121 +0,0 @@
<script setup lang="ts">
import WelcomeItem from "./WelcomeItem.vue";
import DocumentationIcon from "./icons/IconDocumentation.vue";
import ToolingIcon from "./icons/IconTooling.vue";
import EcosystemIcon from "./icons/IconEcosystem.vue";
import CommunityIcon from "./icons/IconCommunity.vue";
import SupportIcon from "./icons/IconSupport.vue";
</script>
<template>
<WelcomeItem>
<template #icon>
<DocumentationIcon />
</template>
<template #heading>Documentation</template>
Vues
<a href="https://vuejs.org/" target="_blank" rel="noopener"
>official documentation</a
>
provides you with all information you need to get started.
</WelcomeItem>
<WelcomeItem>
<template #icon>
<ToolingIcon />
</template>
<template #heading>Tooling</template>
This project is served and bundled with
<a
href="https://vitejs.dev/guide/features.html"
target="_blank"
rel="noopener"
>Vite</a
>. The recommended IDE setup is
<a href="https://code.visualstudio.com/" target="_blank" rel="noopener"
>VSCode</a
>
+
<a
href="https://github.com/johnsoncodehk/volar"
target="_blank"
rel="noopener"
>Volar</a
>. If you need to test your components and web pages, check out
<a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a>
and
<a href="https://on.cypress.io/component" target="_blank"
>Cypress Component Testing</a
>.
<br />
More instructions are available in <code>README.md</code>.
</WelcomeItem>
<WelcomeItem>
<template #icon>
<EcosystemIcon />
</template>
<template #heading>Ecosystem</template>
Get official tools and libraries for your project:
<a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
<a href="https://router.vuejs.org/" target="_blank" rel="noopener"
>Vue Router</a
>,
<a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener"
>Vue Test Utils</a
>, and
<a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener"
>Vue Dev Tools</a
>. If you need more resources, we suggest paying
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
rel="noopener"
>Awesome Vue</a
>
a visit.
</WelcomeItem>
<WelcomeItem>
<template #icon>
<CommunityIcon />
</template>
<template #heading>Community</template>
Got stuck? Ask your question on
<a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a
>, our official Discord server, or
<a
href="https://stackoverflow.com/questions/tagged/vue.js"
target="_blank"
rel="noopener"
>StackOverflow</a
>. You should also subscribe to
<a href="https://news.vuejs.org" target="_blank" rel="noopener"
>our mailing list</a
>
and follow the official
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
>@vuejs</a
>
twitter account for latest news in the Vue world.
</WelcomeItem>
<WelcomeItem>
<template #icon>
<SupportIcon />
</template>
<template #heading>Support Vue</template>
As an independent project, Vue relies on community backing for its
sustainability. You can help us by
<a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener"
>becoming a sponsor</a
>.
</WelcomeItem>
</template>

View File

@ -11,19 +11,14 @@ const connectMetaMask = () => {
ethers.connectProvider(); ethers.connectProvider();
}; };
const makeTransaction = () => { const formatWalletAddress = (): string => {
ethers.makeTransaction()
alert("oi")
};
const formatWalletAddress = (): string => {
const walletAddressLength = walletAddress.value.length; const walletAddressLength = walletAddress.value.length;
const initialText = walletAddress.value.substring(0, 5); const initialText = walletAddress.value.substring(0, 5);
const finalText = walletAddress.value.substring( const finalText = walletAddress.value.substring(
walletAddressLength - 5, walletAddressLength - 5,
walletAddressLength - 1 walletAddressLength - 1
); );
return `${initialText} ... ${finalText}`; return `${initialText}...${finalText}`;
}; };
const formatWalletBalance = (): string => { const formatWalletBalance = (): string => {
@ -44,28 +39,49 @@ const formatWalletBalance = (): string => {
height="75" height="75"
/> />
<div class="flex gap-4 items-center"> <div class="flex gap-4 items-center">
<button <button
type="button" type="button"
class="p-2 rounded text-gray-50" class="default-button"
@click="makeTransaction()"
> >
Quero vender Quero vender
</button> </button>
<button <button
type="button" type="button"
v-if="!walletAddress" v-if="!walletAddress"
class="p-2 border-amber-400 border-2 rounded text-gray-50" class="border-amber-500 border-2 rounded default-button"
@click="connectMetaMask()" @click="connectMetaMask()"
> >
Conectar carteira Conectar carteira
</button> </button>
<div v-if="walletAddress" class="flex gap-4"> <div v-if="walletAddress" class="account-info">
<span class="text-gray-50"> <div class="top-bar-info">
{{ formatWalletAddress() }} <img
</span> alt="Ethereum image"
<span class="text-gray-50"> MBRZ: {{ formatWalletBalance() }} </span> src="@/assets/ethereum.svg"
/>
<span class="default-text">
Ethereum
</span>
<img
alt="Chevron Down"
src="@/assets/chevronDown.svg"
/>
</div>
<div class="top-bar-info">
<img
alt="Account image"
src="@/assets/account.svg"
/>
<span class="default-text text-sm">{{ formatWalletAddress() }}</span>
<img
alt="Chevron Down"
src="@/assets/chevronDown.svg"
/>
</div>
<div class="top-bar-info">
<span class="default-text text-sm"> MBRZ: {{ formatWalletBalance() }} </span>
</div>
<!-- Temporary div, just to show a wallet's balance -->
</div> </div>
</div> </div>
</header> </header>
@ -76,7 +92,18 @@ header {
@apply flex flex-row justify-between w-full items-center; @apply flex flex-row justify-between w-full items-center;
} }
.logo { .default-button{
display: block; @apply px-4 py-2 rounded text-gray-50 font-semibold text-base
}
.account-info{
@apply flex items-center gap-6
}
.default-text{
@apply text-gray-50 font-semibold text-base
}
.top-bar-info{
@apply flex justify-between gap-2 px-4 py-2 border-amber-500 border-2 rounded
} }
</style> </style>

View File

@ -1,86 +0,0 @@
<template>
<div class="item">
<i>
<slot name="icon"></slot>
</i>
<div class="details">
<h3>
<slot name="heading"></slot>
</h3>
<slot></slot>
</div>
</div>
</template>
<style scoped>
.item {
margin-top: 2rem;
display: flex;
}
.details {
flex: 1;
margin-left: 1rem;
}
i {
display: flex;
place-items: center;
place-content: center;
width: 32px;
height: 32px;
color: var(--color-text);
}
h3 {
font-size: 1.2rem;
font-weight: 500;
margin-bottom: 0.4rem;
color: var(--color-heading);
}
@media (min-width: 1024px) {
.item {
margin-top: 0;
padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
}
i {
top: calc(50% - 25px);
left: -26px;
position: absolute;
border: 1px solid var(--color-border);
background: var(--color-background);
border-radius: 8px;
width: 50px;
height: 50px;
}
.item:before {
content: " ";
border-left: 1px solid var(--color-border);
position: absolute;
left: 0;
bottom: calc(50% + 25px);
height: calc(50% - 25px);
}
.item:after {
content: " ";
border-left: 1px solid var(--color-border);
position: absolute;
left: 0;
top: calc(50% + 25px);
height: calc(50% - 25px);
}
.item:first-of-type:before {
display: none;
}
.item:last-of-type:after {
display: none;
}
}
</style>

View File

@ -1,12 +0,0 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
>
<path
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
/>
</svg>
</template>

View File

@ -1,12 +0,0 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="17"
fill="currentColor"
>
<path
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
/>
</svg>
</template>

View File

@ -1,12 +0,0 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="20"
fill="currentColor"
>
<path
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
/>
</svg>
</template>

View File

@ -1,12 +0,0 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
>
<path
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
/>
</svg>
</template>

View File

@ -1,19 +0,0 @@
<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--mdi"
width="24"
height="24"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
>
<path
d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
fill="currentColor"
></path>
</svg>
</template>

11
src/model/Pix.ts Normal file
View File

@ -0,0 +1,11 @@
export type Pix = {
pixKey: string;
merchantCity?: string;
merchantName?: string;
value?: number;
transactionId?: string;
message?: string;
cep?: string;
currency?: number;
countryCode?: string;
};

View File

@ -1,5 +1,6 @@
import { createRouter, createWebHistory } from "vue-router"; import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue"; import HomeView from "../views/HomeView.vue";
import QrCodeFormVue from "../views/QrCodeForm.vue";
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(import.meta.env.BASE_URL),
@ -9,18 +10,10 @@ const router = createRouter({
name: "home", name: "home",
component: HomeView, component: HomeView,
}, },
{
path: "/ethers",
name: "ethers",
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import("../views/EthersView.vue"),
},
{ {
path: "/pix", path: "/pix",
name: "pix", name: "pix",
component: () => import("../views/QrCodeForm.vue"), component: QrCodeFormVue,
}, },
], ],
}); });

View File

@ -1,18 +1,7 @@
import qrcode from "qrcode"; import qrcode from "qrcode";
import type { QRCodeToDataURLOptions } from "qrcode"; import type { QRCodeToDataURLOptions } from "qrcode";
import { crc16ccitt } from "crc"; import { crc16ccitt } from "crc";
import {type Pix } from "@/model/Pix";
interface PixParams {
pixKey: string;
merchantCity?: string;
merchantName?: string;
value?: number;
transactionId?: string;
message?: string;
cep?: string;
currency?: number;
countryCode?: string;
}
const pix = ({ const pix = ({
pixKey, pixKey,
@ -24,7 +13,7 @@ const pix = ({
transactionId = "***", transactionId = "***",
currency = 986, currency = 986,
countryCode = "BR", countryCode = "BR",
}: PixParams) => { }: Pix) => {
const payloadKeyString = generatePixKey(pixKey, message); const payloadKeyString = generatePixKey(pixKey, message);
const payload: string[] = [ const payload: string[] = [
@ -84,4 +73,4 @@ const formatEMV = (id: string, param: string): string => {
return `${id}${len}${param}`; return `${id}${len}${param}`;
}; };
export { type PixParams, pix }; export { pix };

View File

@ -8,12 +8,9 @@ import addresses from "../../../p2pix-smart-contracts/deploys/localhost.json"
const updateWalletStatus = async (walletAddress: string) => { const updateWalletStatus = async (walletAddress: string) => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
const window_ = window as any; const provider = getProvider();
const connection = window_.ethereum; if(!provider) return;
if (!connection) return;
const provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner(); const signer = provider.getSigner();
const contract = new ethers.Contract(addresses.token, mocktoken.abi, signer); const contract = new ethers.Contract(addresses.token, mocktoken.abi, signer);
@ -29,33 +26,27 @@ const connectProvider = async () => {
const connection = window_.ethereum; const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null; let provider: ethers.providers.Web3Provider | null = null;
if (connection) { if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const contract = new ethers.Contract(addresses.token, mocktoken.abi, signer);
provider = new ethers.providers.Web3Provider(connection); const walletAddress = await provider.send("eth_requestAccounts", []);
const signer = provider.getSigner(); const balance = await contract.balanceOf(walletAddress[0]);
const contract = new ethers.Contract(addresses.token, mocktoken.abi, signer);
const walletAddress = await provider.send("eth_requestAccounts", []); etherStore.setWalletAddress(walletAddress[0]);
const balance = await contract.balanceOf(walletAddress[0]); etherStore.setBalance(String(balance));
etherStore.setWalletAddress(walletAddress[0]); connection.on("accountsChanged", (accounts: string[]) => {
etherStore.setBalance(String(balance)); updateWalletStatus(accounts[0]);
});
connection.on("accountsChanged", (accounts: string[]) => {
updateWalletStatus(accounts[0]);
});
}
}; };
const makeTransaction = async () => { const makeTransaction = async () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
const window_ = window as any; const provider = getProvider();
const connection = window_.ethereum; if(!provider) return;
let provider: ethers.providers.Web3Provider | null = null;
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner(); const signer = provider.getSigner();
const contract = new ethers.Contract(addresses.token, mocktoken.abi, signer); const contract = new ethers.Contract(addresses.token, mocktoken.abi, signer);
@ -71,4 +62,13 @@ const formatEther = (balance: string) => {
return formatted; return formatted;
}; };
const getProvider = (): ethers.providers.Web3Provider | null => {
const window_ = window as any;
const connection = window_.ethereum;
if (!connection) return null;
return new ethers.providers.Web3Provider(connection);
}
export default { connectProvider, formatEther, makeTransaction }; export default { connectProvider, formatEther, makeTransaction };

View File

@ -1,30 +0,0 @@
<script setup lang="ts">
import ethers from "../utils/ethers";
const connectMetaMask = () => {
ethers.connectProvider();
};
</script>
<template>
<div class="about">
<button
class="rounded-lg w-full border border-emerald-900 text-white py-2 bg-emerald-600 hover:bg-emerald-500 mt-4"
@click="connectMetaMask()"
>
Conectar metaMask
</button>
</div>
</template>
<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
}
</style>

View File

@ -1,9 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import TheWelcome from "../components/TheWelcome.vue";
</script> </script>
<template> <template>
<main>
<TheWelcome />
</main>
</template> </template>

View File

@ -49,145 +49,150 @@ const submit = () => {
</script> </script>
<template> <template>
<div class="container"> <div class="page">
<h2 class="text-center font-bold text-emerald-50 text-2xl"> <div class="form-container">
pixModel QR Code <h2 class="text-center font-bold text-emerald-50 text-2xl">
</h2> pixModel QR Code
<form> </h2>
<div class="grid gap-4 grid-cols-1 p-2"> <form>
<div class="col-div"> <div class="grid gap-4 grid-cols-1 p-2">
<div class="mb-2"> <div class="col-div">
<label for="pixKey" class="form-label">Chave PIX</label> <div class="mb-2">
<span v-if="errors['pixRequiredError']" class="required-error" <label for="pixKey" class="form-label">Chave PIX</label>
>(Esse campo é obrigatório)</span <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>
<input <div class="col-div">
type="text" <label for="code" class="form-label"
name="pixKey" >Código da transferência (Opcional)</label
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
> >
<input
type="text"
name="code"
id="code"
class="form-input"
v-model="pixModel.transactionId"
/>
</div> </div>
<input <div class="col-div">
type="text" <label for="message" class="form-label">Mensagem (Opcional)</label>
name="name" <input
id="name" type="text"
class="form-input" name="message"
v-model="pixModel.name" id="message"
/> class="form-input"
</div> v-model="pixModel.message"
<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> </div>
<input <button type="button" class="button" @click="submit">
type="text" Gerar QR code
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
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> </button>
</div> </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>
<div
v-if="toggleModal"
class="fixed z-40 inset-0 opacity-25 bg-black"
></div>
</div> </div>
<div
v-if="toggleModal"
class="fixed z-40 inset-0 opacity-25 bg-black"
></div>
</template> </template>
<style scoped> <style scoped>
.container { .page {
@apply mt-8 w-full flex justify-center self-center;
}
.form-container{
background-color: var(--color-background-indigo); background-color: var(--color-background-indigo);
@apply rounded-md p-2 mt-8; @apply rounded-md w-full p-2 w-1/2
} }
.col-div { .col-div {