|
@@ -0,0 +1,386 @@
|
|
|
+<template>
|
|
|
+ <div class="nft-detail-wrapper">
|
|
|
+ <div class="back-bar">
|
|
|
+ <img :src="require('@/assets/svg/icon-nft-back-arrow.svg')" class="icon-arrow" @click="back" />
|
|
|
+ {{ NFTInfo.nftItemName }}
|
|
|
+ </div>
|
|
|
+ <div class="content">
|
|
|
+ <div class="nft-img">
|
|
|
+ <img class="img" :src="NFTInfo.imagePath" @click="clickNFTImg" v-if="NFTInfo.imagePath" />
|
|
|
+ <nft-card :nftItemId="NFTInfo.nftItemId" :item="NFTInfo.createImageInfo" :width="343" v-else>
|
|
|
+ </nft-card>
|
|
|
+ </div>
|
|
|
+ <div class="desc item" v-if="nftMetaData.description">
|
|
|
+ <div class="title">Description</div>
|
|
|
+ <div class="desc-content" v-html="nftMetaData.description"></div>
|
|
|
+ </div>
|
|
|
+ <div class="prop item" v-if="nftMetaData.properties && nftMetaData.properties.length">
|
|
|
+ <div class="title">Properties</div>
|
|
|
+ <div class="prop-content">
|
|
|
+ <div class="prop-item" v-for="(filedValueItem, filedValueIndex) in nftMetaData.properties"
|
|
|
+ :key="filedValueIndex">
|
|
|
+ {{ filedValueItem.name }}
|
|
|
+ <div class="prop-name">
|
|
|
+ {{ filedValueItem.value }}
|
|
|
+ </div>
|
|
|
+ {{ filedValueItem.description }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="about item" v-if="nftMetaData.about">
|
|
|
+ <div class="title">About</div>
|
|
|
+ <div class="about-content" v-html="nftMetaData.about"></div>
|
|
|
+ </div>
|
|
|
+ <div class="detail item" v-if="nftDetailData.details">
|
|
|
+ <div class="title">Details</div>
|
|
|
+ <div class="detail-content">
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="left">Contract Address</div>
|
|
|
+ <div class="right address" @click="clickAddress">
|
|
|
+ <span>{{ nftDetailData.details.contractAddress }}</span>
|
|
|
+ <span>{{ nftDetailData.details.contractAddress }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="left">Token ID</div>
|
|
|
+ <div class="right token" @click="clickToken">
|
|
|
+ {{ nftDetailData.details.tokenId }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="left">Token Standard</div>
|
|
|
+ <div class="right">
|
|
|
+ {{ nftDetailData.details.tokenStandard }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="left">Blockchain</div>
|
|
|
+ <div class="right">
|
|
|
+ {{ nftDetailData.details.blockChain }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="left">Creator Fees</div>
|
|
|
+ <div class="right">
|
|
|
+ {{ nftDetailData.details.creatorFees }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="left">Transaction Royalties</div>
|
|
|
+ <div class="right">
|
|
|
+ {{ nftDetailData.details.transactionRoyalties }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="date item" v-if="nftDetailData.dateOfPossession">
|
|
|
+ <div class="title">Date of possession</div>
|
|
|
+ <div class="date-content">{{ nftDetailData.dateOfPossession }}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="price item" v-if="nftDetailData.purchasePrice">
|
|
|
+ <div class="title">Purchase price</div>
|
|
|
+ <div class="price-content">{{ nftDetailData.purchasePrice }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="bottom-bar">
|
|
|
+ <div class="sale" @click="transfer">
|
|
|
+ <span>Transfer</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted } from "vue";
|
|
|
+import { useRouter } from "vue-router";
|
|
|
+import nftCard from "@/components/nft-card.vue";
|
|
|
+import { getNFTDetail } from "@/http/nft.js";
|
|
|
+import messageCenter from "@/uilts/messageCenter";
|
|
|
+import MESSAGE_ENUM from "@/uilts/messageCenter/messageEnum";
|
|
|
+
|
|
|
+let timer = ref(null);
|
|
|
+let nftMetaData = ref({});
|
|
|
+let nftDetailData = ref({});
|
|
|
+let router = useRouter();
|
|
|
+
|
|
|
+let NFTInfo = ref({
|
|
|
+ imagePath: '',
|
|
|
+ nftItemName: ''
|
|
|
+});
|
|
|
+
|
|
|
+const back = () => {
|
|
|
+ messageCenter.send({
|
|
|
+ actionType: MESSAGE_ENUM.IFRAME_SHOW_FOOTER_MENU,
|
|
|
+ data: {
|
|
|
+ showMenu: true,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ router.back();
|
|
|
+};
|
|
|
+
|
|
|
+const clickAddress = () => {
|
|
|
+ let { contractAddressUrl = '' } = nftDetailData.value.details;
|
|
|
+ if (contractAddressUrl) {
|
|
|
+ window.open(contractAddressUrl);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const clickToken = () => {
|
|
|
+ let { tokenIdUrl = '' } = nftDetailData.value.details;
|
|
|
+ if (tokenIdUrl) {
|
|
|
+ window.open(tokenIdUrl);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const clickNFTImg = () => {
|
|
|
+ // window.open(NFTInfo.value.imagePath);
|
|
|
+};
|
|
|
+
|
|
|
+const getDetail = () => {
|
|
|
+ getNFTDetail({
|
|
|
+ params: {
|
|
|
+ nftItemId: NFTInfo.value.nftItemId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.code == 0) {
|
|
|
+ console.log(res)
|
|
|
+ let { metadata = '{}' } = res.data || {};
|
|
|
+ nftDetailData.value = res.data;
|
|
|
+ nftMetaData.value = JSON.parse(metadata);
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const transfer = () => {
|
|
|
+ if (Object.keys(nftDetailData.value).length) {
|
|
|
+ clearTimeout(timer.value);
|
|
|
+ router.push({
|
|
|
+ name: 'NFTTransfer',
|
|
|
+ query: {
|
|
|
+ params: JSON.stringify({
|
|
|
+ nftItemId: nftDetailData.value?.nftItemId,
|
|
|
+ chainInfo: nftDetailData.value?.chainInfo,
|
|
|
+ transferFeeCurrencyInfo: nftDetailData.value?.transferFeeCurrencyInfo,
|
|
|
+ transferFeeAmountValue: nftDetailData.value?.transferFeeAmountValue,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ clearTimeout(timer.value);
|
|
|
+ timer.value = setTimeout(() => {
|
|
|
+ transfer()
|
|
|
+ }, 300)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ let { params = '{}' } = router.currentRoute.value.query;
|
|
|
+ NFTInfo.value = JSON.parse(params);
|
|
|
+ getDetail();
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.nft-detail-wrapper {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ .back-bar {
|
|
|
+ height: 48px;
|
|
|
+ background: #ffffff;
|
|
|
+ box-shadow: 0px 0.5px 0px #d1d9dd;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .icon-arrow {
|
|
|
+ width: 24px;
|
|
|
+ margin-right: 12px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100% - 120px);
|
|
|
+ padding: 0 16px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ overflow-y: auto;
|
|
|
+
|
|
|
+ .nft-img {
|
|
|
+ margin-top: 23px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ .img {
|
|
|
+ width: 280px;
|
|
|
+ border-radius: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .item {
|
|
|
+ border: 1px solid #e3e3e3;
|
|
|
+ border-radius: 10px;
|
|
|
+ padding: 14px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ margin-bottom: 12px;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .desc {
|
|
|
+ margin-top: 10px;
|
|
|
+
|
|
|
+ .desc-content {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #929292;
|
|
|
+
|
|
|
+ span {
|
|
|
+ color: #1d9bf0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prop {
|
|
|
+ .prop-content {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ margin-top: 12px;
|
|
|
+
|
|
|
+ .prop-item {
|
|
|
+ width: 48%;
|
|
|
+ min-height: 88px;
|
|
|
+ background: #f8f8f8;
|
|
|
+ border-radius: 10px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 8px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #929292;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .prop-name {
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 17px;
|
|
|
+ margin-top: 6px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ color: #000;
|
|
|
+ word-break: break-all;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prop-item:nth-child(odd) {
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .about-content {
|
|
|
+ margin-top: 22px;
|
|
|
+
|
|
|
+ .section {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 14px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .section {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 14px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail-content {
|
|
|
+ margin-top: 15px;
|
|
|
+
|
|
|
+ .detail-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ height: 24px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ .right {
|
|
|
+ color: #929292;
|
|
|
+ }
|
|
|
+
|
|
|
+ .token {
|
|
|
+ color: #1d9bf0 !important;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .address {
|
|
|
+ width: 100px;
|
|
|
+ white-space: nowrap;
|
|
|
+ color: #1d9bf0 !important;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ >span {
|
|
|
+ display: inline-block;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ width: 50%;
|
|
|
+
|
|
|
+ +span {
|
|
|
+ width: calc(50% + 10px);
|
|
|
+ direction: rtl;
|
|
|
+ margin-left: -11px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-content,
|
|
|
+ .price-content {
|
|
|
+ margin-top: 10px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #929292;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom-bar {
|
|
|
+ background: #ffffff;
|
|
|
+ box-shadow: inset 0px 1px 0px #ececec;
|
|
|
+ height: 70px;
|
|
|
+ padding: 0 16px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: right;
|
|
|
+
|
|
|
+ .sale {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ cursor: pointer;
|
|
|
+ width: 97px;
|
|
|
+ height: 37px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #1D9BF0;
|
|
|
+ border-radius: 20px;
|
|
|
+ border: 1px solid #1D9BF0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|