2024-07-02 14:38:51 +08:00

409 lines
10 KiB
Vue

<template>
<div class="cart" v-if="cartList">
<div class="cart-header">
<div>My Cart <span>( {{ cartList.length }} )</span> <span @click="clearCart">Clear</span></div>
<div class="close" @click="closeCart">
<img src="@/assets/img/marketplace/closeicon.png" alt="">
</div>
</div>
<div class="cart-content">
<div v-if="cartList !== undefined && cartList.length > 0" class="cart-list">
<li class="cart-item" v-for="(item, index) in cartList" :key="index">
<div class="cart-item-left">
<div class="cart-item-left-img">
<ImgCard :nftData="item.nft" />
</div>
<div class="cart-item-left-name">{{ item.nft.name }}</div>
</div>
<div class="cart-item-right">
<div class="cart-item-right-price">
<div>{{ priceCalculated(item.amount, item.decimals) }}</div>
<div class="cart-item-right-price-img">
<img :src="item.icon" alt="">
</div>
</div>
<div class="cart-item-right-clear" @click="deleteNft(item)">
<img src="@/assets/img/marketplace/Delete_icon.png" alt="">
</div>
</div>
</li>
</div>
<div v-else class="cart-not">
<p>You have no items in your cart</p>
</div>
</div>
<div class="cart-total-price">
<template v-for="(item, index) in priceList" :key="index">
<div :class="{'top': index == 0, 'bottom': index > 0}">
<div class="left" v-if="index == 0">Total Price</div>
<div class="left" v-if="index > 0"></div>
<div class="right">{{ priceCalculated(item.amount, item.decimals) }} <img :src="item.icon" alt=""></div>
</div>
</template>
<div class="bottom">
<div class="left"></div>
<div class="right">
<div v-if="priceList.length > 0"> {{ usdTotal }}$</div>
</div>
</div>
</div>
<div v-if="cartList !== undefined && cartList.length > 0" class="cart-btn" @click="buyAll">Buy All</div>
<div v-else class="cart-btn" @click="toMarketplace">Select NFTs to Buy</div>
</div>
</template>
<script setup>
import { ref, onMounted, inject } from "vue"
const message = inject('$message')
import ImgCard from "@/components/common/imgCard.vue"
import ConfirmDialog from "@/components/Dialogs/confirmDialog.vue";
import BuyDialog from "@/components/Dialogs/buyDialog.vue"
import { useRouter } from "vue-router";
import { useMarketplaceStore } from "@/store/marketplace"
import {priceCalculated, completePrice} from "@/configs/priceCalculate.js"
import {createModal} from "@/utils/model.util";
import {formatPrice} from "@/components/chain/utils"
const marketplaceList = useMarketplaceStore()
import {
apiDelCartList,
apiClearCartList,
} from "@/utils/marketplace"
import { computed } from "vue";
const router = useRouter();
const emit = defineEmits(['clickStatusChild'])
const cartList = ref()
const closeCart = () => {
emit('closeCart')
}
const toMarketplace = () => {
emit('closeCart')
router.push('/marketplace');
}
const priceList = computed(() => {
let map = new Map()
for (let item of cartList.value) {
if (!map.has(item.currencyName)) {
map.set(item.currencyName, {
icon: item.icon,
amount: 0n,
})
}
let data = map.get(item.currencyName)
data.amount += item.amount
data.decimals = item.decimals
map.set(item.currencyName, data)
}
let result = []
for (let [key, value] of map) {
result.push(value)
}
return result
});
const usdTotal = computed(() => {
let total = 0
for (let item of cartList.value) {
total += Number(item.usd)
}
return total.toFixed(2)
})
// 获取购物车列表
const getCartList = async () => {
// let token = localStorage.getItem('assessToken')
// if(token) {
try {
let res = await marketplaceList.getCartListState()
console.log(res)
if (res.data && res.data.length > 0) {
for (let sub of res.data) {
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
}
}
}
console.log(res)
cartList.value = res.data
marketplaceList.getCartList = res
} catch (e) {
console.log(e)
}
// }
}
// 删除nft
const deleteNft = async (val) => {
const data = {
net_id: import.meta.env.VUE_APP_NET_ID,
tokens: [
{
token_id: val.nft.token_id,
contract_address: val.nft.contract_address,
}
]
}
try {
const { errcode, errmsg } = await marketplaceList.delCartListState(data)
if(errcode == 0) {
message.success('success! Remove from cart')
getCartList()
}
} catch (e) {
console.log(e)
}
}
// 清空购物车
const clearCart = async () => {
if (cartList.value.length === 0) {
return
}
try {
const confirmResult = await createModal(ConfirmDialog, {
title: 'Confirm Clear Cart',
message: 'Are you sure you want to clear the cart?'
}).show()
if (confirmResult.errcode) {
console.log('user cancel')
return
}
const res = await apiClearCartList()
if (res.errcode) {
throw new Error(res.errmsg)
}
message.success('success! Remove from cart')
await getCartList()
} catch (e) {
console.log(e)
}
}
const buyAll = async () => {
try {
const confirmResult = await createModal(BuyDialog, {
buyDataArr: cartList.value,
}).show()
if(confirmResult.errcode == 1) {
console.log('buy fail')
message.error('buy fail')
return
} else {
getCartList()
message.success('success! Buy')
}
} catch (e) {
message.error('buy fail')
}
}
// watch(() => route.path,(newPath, oldPath) => {
// let routerPath = newPath.split('/')
// if(routerPath[1] == 'marketplace' || routerPath[1] == 'assets' || routerPath[1] == 'detail') {
// isCart.value = true
// } else {
// isCart.value = false
// }
// })
onMounted(()=> {
getCartList()
})
</script>
<style lang="scss" scoped>
.cart {
width: 570px;
// height: 100%;
color: #BB7FFF;
border-radius: 30px;
.cart-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30px;
padding-bottom: 5px;
border-bottom: 2px solid #3D4057;
div {
font-family: 'Poppins';
font-weight: bold;
font-size: 22px;
color: #fefefe;
span {
color: #00FF00;
margin-left: 10px;
cursor: pointer;
}
}
.close {
width: 30px;
height: 30px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
.cart-content {
padding: 0 15px;
.cart-not {
height: 183px;
line-height: 183px;
margin-top: 20px;
text-align: center;
margin-bottom: 30px;
font-size: 24px;
color: #fff;
}
.cart-list {
.cart-item {
display: flex;
justify-content: space-between;
width: 532px;
padding: 15px;
border-radius: 16px;
margin: 0 auto;
margin-top: 5px;
box-sizing: border-box;
.cart-item-left {
display: flex;
.cart-item-left-img {
width: 110px;
height: 165px;
:deep(.card-img-common) {
.img-top {
width: 35px;
height: 12px;
top: 10px;
left: 10px;
font-size: 8px;
}
.img-btm {
bottom: 8px;
left: 12px;
>div {
width: 35px;
height: 12px;
font-size: 8px;
}
div:nth-child(2) {
margin-left: 3px;
}
}
}
}
.cart-item-left-name {
font-family: 'Poppins';
font-weight: bold;
font-size: 24px;
color: #fff;
margin-left: 29px;
}
}
.cart-item-right {
height: 40px;
.cart-item-right-price {
display: flex;
align-items: center;
div {
height: 27px;
line-height: 27px;
font-family: 'Poppins';
font-weight: bold;
font-size: 24px;
color: #984FFB;
}
.cart-item-right-price-img {
width: 27px;
height: 27px;
margin-left: 10px;
img {
width: 100%;
height: 100%;
}
}
}
.cart-item-right-clear {
display: none;
width: 39px;
height: 40px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
&:hover {
.cart-item-right-price {
display: none;
}
.cart-item-right-clear {
display: block;
}
}
}
&:hover {
background: #27232d;
}
}
}
}
.cart-total-price {
width: 494px;
margin: 0 auto;
margin-top: 63px;
>div {
display: flex;
justify-content: space-between;
align-items: center;
height: 35px;
font-family: 'Poppins';
font-weight: bold;
color: #BB7FFF;
}
.left {
font-size: 42px;
}
.right {
display: flex;
align-items: center;
font-size: 24px;
img {
width: 27px;
height: 27px;
margin-left: 8px;
}
}
}
.cart-btn {
width: 494px;
height: 60px;
line-height: 60px;
margin: 0 auto;
margin-top: 10px;
margin-bottom: 40px;
font-family: 'Poppins';
font-weight: bold;
font-size: 30px;
background: #6336D7;
color: #fff;
text-align: center;
border-radius: 18px;
cursor: pointer;
}
}
</style>