283 lines
6.9 KiB
Vue
283 lines
6.9 KiB
Vue
<template>
|
|
<div class="buy-dialog" ref="buyModal" v-if="props.visible">
|
|
<div class="top-close" @click="handleCancel">
|
|
<img src="@/assets/img/marketplace/Close_counter.png" alt />
|
|
</div>
|
|
<div class="buy-dialog-content">
|
|
<div class="content">
|
|
<div class="content-title">Transaction confirmation ( {{ props.buyDataArr.length }} )</div>
|
|
<div class="content-table">
|
|
<div>NFT</div>
|
|
<div>Token ID</div>
|
|
<div>Price</div>
|
|
</div>
|
|
<div class="content-nfts" v-for="(item, index) in props.buyDataArr" :key="index">
|
|
<li>
|
|
<div class="nft">
|
|
<div class="nft-img">
|
|
<img :src="item.nft.image" alt />
|
|
</div>
|
|
<div class="nft-name">{{ item.nft.name }}</div>
|
|
</div>
|
|
<div class="id">{{ item.nft.token_id }}</div>
|
|
<div class="price">
|
|
<div>{{ item.tokenAmount }}</div>
|
|
<div class="price-img">
|
|
<img :src="item.icon" alt />
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</div>
|
|
</div>
|
|
<div class="btm">
|
|
<div class="btm-left">
|
|
<li>Total : </li>
|
|
<li>
|
|
<div>
|
|
<span>{{ totalPrice }}</span>
|
|
<img :src="props.buyDataArr[0].icon" alt />
|
|
</div>
|
|
</li>
|
|
</div>
|
|
<div class="btm-right" @click="buyConfirm">Confirm</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
import {ref, toRaw, computed, onMounted} from "vue";
|
|
import {Modal} from "ant-design-vue";
|
|
import {priceCalculated} from "@/configs/priceCalculate";
|
|
import {BlockChain} from "@/components/chain/BlockChain";
|
|
import { formatPrice } from "@/components/chain/utils";
|
|
const props = defineProps({
|
|
buyDataArr: {
|
|
type: Array,
|
|
required: true,
|
|
},
|
|
visible: ref(Boolean),
|
|
close: Function,
|
|
});
|
|
const totalPrice = computed(() => {
|
|
let total = 0n;
|
|
for (let sub of props.buyDataArr) {
|
|
total += sub.amount || 0n;
|
|
}
|
|
return priceCalculated(total, props.buyDataArr[0].decimals);
|
|
});
|
|
const emit = defineEmits(["handleClose"]);
|
|
|
|
const handleOk = (e) => {
|
|
emit("handleClose");
|
|
};
|
|
|
|
const buyConfirm = async () => {
|
|
const lists = toRaw(props.buyDataArr);
|
|
const ids = lists.map((item) => item.event.data.id);
|
|
const bc = new BlockChain();
|
|
try {
|
|
let res = await bc.market.batchBuy(ids);
|
|
if (res != undefined && res.length > 0) {
|
|
hideModal({errcode: 0});
|
|
}
|
|
} catch (err) {
|
|
console.log("buy fail", err);
|
|
hideModal({errcode: 1, err});
|
|
}
|
|
};
|
|
|
|
const handleCancel = (e) => {
|
|
hideModal({errcode: 1});
|
|
};
|
|
|
|
function hideModal(result = null) {
|
|
props.close(result);
|
|
}
|
|
|
|
onMounted(() => {
|
|
for (let sub of props.buyDataArr) {
|
|
if (sub.event?.data) {
|
|
const _data = formatPrice(sub.event.data)
|
|
sub.icon = _data.icon
|
|
sub.usd = _data.usd
|
|
sub.currencyName = _data.currencyName
|
|
sub.amount = _data.amount
|
|
sub.tokenAmount = _data.tokenAmount
|
|
sub.decimals = _data.decimals
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.buy-dialog {
|
|
position: fixed;
|
|
top: 20%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
color: #fff;
|
|
width: 1140px;
|
|
min-height: 500px;
|
|
padding: 0px;
|
|
background: #1a1821;
|
|
border: 1px solid #b966ff;
|
|
box-shadow: 0px 15px 28px 3px rgba(22, 22, 22, 0.13);
|
|
border-radius: 100px;
|
|
.top-close {
|
|
position: absolute;
|
|
top: -23px;
|
|
right: -23px;
|
|
width: 106px;
|
|
height: 106px;
|
|
cursor: pointer;
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
.buy-dialog-content {
|
|
margin-top: 40px;
|
|
.content {
|
|
.content-title {
|
|
font-family: "Anton";
|
|
font-weight: 400;
|
|
font-size: 48px;
|
|
margin-left: 50px;
|
|
}
|
|
.content-table {
|
|
width: 1017px;
|
|
height: 48px;
|
|
line-height: 48px;
|
|
margin: 0 auto;
|
|
background: #2d2738;
|
|
border-radius: 20px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
color: #a8a5ac;
|
|
font-size: 14px;
|
|
div {
|
|
width: 240px;
|
|
text-align: center;
|
|
&:nth-child(1) {
|
|
width: 540px;
|
|
text-align: left;
|
|
padding-left: 100px;
|
|
box-sizing: border-box;
|
|
}
|
|
&:nth-child(2) {
|
|
width: 340px;
|
|
text-align: center;
|
|
box-sizing: border-box;
|
|
}
|
|
&:nth-child(3) {
|
|
text-align: right;
|
|
padding-right: 100px;
|
|
box-sizing: border-box;
|
|
}
|
|
}
|
|
}
|
|
.content-nfts {
|
|
width: 1017px;
|
|
margin: 0 auto;
|
|
li {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin: 20px 0;
|
|
> div {
|
|
width: 240px;
|
|
font-family: "Poppins";
|
|
font-weight: 500;
|
|
font-size: 30px;
|
|
text-align: center;
|
|
}
|
|
.nft {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 540px;
|
|
.nft-img {
|
|
width: 110px;
|
|
height: 164px;
|
|
border: 1px solid #fff;
|
|
margin-left: 50px;
|
|
}
|
|
.nft-name {
|
|
font-weight: bold;
|
|
margin-left: 20px;
|
|
}
|
|
}
|
|
.id {
|
|
width: 340px;
|
|
}
|
|
.price {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
.price-img {
|
|
width: 28px;
|
|
height: 28px;
|
|
margin-left: 10px;
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.btm {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-left: 60px;
|
|
padding-top: 20px;
|
|
border-top: 2px solid #3a3b57;
|
|
box-sizing: border-box;
|
|
.btm-left {
|
|
display: flex;
|
|
margin-left: 20px;
|
|
li {
|
|
font-family: "Anton";
|
|
font-weight: 400;
|
|
font-size: 42px;
|
|
color: #bb7fff;
|
|
div {
|
|
display: flex;
|
|
align-items: center;
|
|
img {
|
|
width: 39px;
|
|
height: 39px;
|
|
margin-left: 20px;
|
|
}
|
|
}
|
|
.money {
|
|
font-family: "Poppins";
|
|
font-weight: 400;
|
|
font-size: 24px;
|
|
}
|
|
}
|
|
}
|
|
.btm-right {
|
|
width: 240px;
|
|
height: 40px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
line-height: 40px;
|
|
margin-right: 20px;
|
|
background: #fec25d;
|
|
color: #2d2738;
|
|
font-family: "Poppins";
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
text-align: center;
|
|
border-radius: 20px;
|
|
box-shadow: 0 0 5px 0px #fec25d;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |