增加官方商城页面
This commit is contained in:
parent
d1e867d3f2
commit
f63ac1c666
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="card-list">
|
||||
<div class="grid">
|
||||
<card v-for="c in cardList" :key="c"></card>
|
||||
<nft-item v-for="c in cardList" :key="c.id" :data="c" class="item"></nft-item>
|
||||
</div>
|
||||
<pagination></pagination>
|
||||
</div>
|
||||
@ -9,17 +9,24 @@
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import Pagination from '@/components/market/Pagination.vue'
|
||||
import Card from '@/components/market/Card.vue'
|
||||
import NftItem from '@/components/market/NftItem.vue'
|
||||
import { ISpineData } from '@/utils/SpineRender'
|
||||
|
||||
@Component({
|
||||
name: 'CardList',
|
||||
components: {
|
||||
Card,
|
||||
NftItem,
|
||||
Pagination
|
||||
}
|
||||
})
|
||||
export default class extends Vue {
|
||||
private cardList: number[] = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
private cardList: ISpineData[] = []
|
||||
|
||||
created() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
this.cardList.push({ id: 'hero2_10' + i, type: 0, skelName: 'n_aoi', name: 'miffy', price: '10', class: 0, repeat: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@ -47,6 +54,7 @@ export default class extends Vue {
|
||||
.card-list .grid .item {
|
||||
height: 21em;
|
||||
width: 14.375em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
|
@ -10,8 +10,8 @@
|
||||
<img src="data:image/svg+xml,%3csvg width='28' height='20' viewBox='0 0 28 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath d='M0 3.33333V0H28V3.33333L0 3.33333Z' fill='white' /%3e %3cpath d='M0 11.6667H28V8.33333H0V11.6667Z' fill='white' /%3e %3cpath d='M0 20H28V16.6667H0V20Z' fill='white' /%3e %3c/svg%3e"></label>
|
||||
</div>
|
||||
<div class="nav overflow" :class="{'show': menuShow}">
|
||||
<label class="navItem">Official Store</label>
|
||||
<label class="navItem dash">Marketplace</label>
|
||||
<a class="navItem" href="/official">Official Shop</a>
|
||||
<a class="navItem dash" href="/market">Marketplace</a>
|
||||
<button v-if="!walletCollected" class="general-btn connectButton mobile" @click="collectToWallet">
|
||||
<span>Connect Wallet</span>
|
||||
</button>
|
||||
@ -80,7 +80,7 @@ export default class extends Vue {
|
||||
background: rgba(20,16,59,.8);
|
||||
box-shadow: 0 1em 1.5em rgba(0,0,0,0.15);
|
||||
backdrop-filter: blur(5em);
|
||||
z-index: 8;
|
||||
z-index: 18;
|
||||
height: 4.75em;
|
||||
position: fixed;
|
||||
padding: 0 5%;
|
||||
@ -108,7 +108,7 @@ export default class extends Vue {
|
||||
|
||||
transform: translateX(100%);
|
||||
display: flex;
|
||||
z-index: 7;
|
||||
z-index: 17;
|
||||
opacity: 0;
|
||||
transition: transform linear 0.2s, opacity linear 0.2s;
|
||||
padding: 1.5em 1.5em;
|
||||
@ -148,6 +148,7 @@ export default class extends Vue {
|
||||
line-height: 1.5em;
|
||||
color: #ffffff;
|
||||
padding: 1.5em 0;
|
||||
text-decoration: none;
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid #3d2a84;
|
||||
|
121
src/components/market/NftItem.vue
Normal file
121
src/components/market/NftItem.vue
Normal file
@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<router-link class="card" to="/item">
|
||||
<img class="bg-img" src="@/assets/main/card/card_border.png">
|
||||
<div class="anim-border">
|
||||
<img class="card-main-img" :src="require(`@/assets/main/card/${data.skelName}.png`)" />
|
||||
<img class="name-img" :src="require('@/assets/main/card/'+data.name+'.png')">
|
||||
<div class="info-div">
|
||||
<img class='buy-icon' src="@/assets/main/card/icon_buy.png"/>
|
||||
<div class="price-label"><span>{{data.price}}</span></div>
|
||||
</div>
|
||||
<div class="class-div">
|
||||
<img :src="require('@/assets/main/card/class_'+data.class+'.png')">
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import { ISpineData } from '@/utils/SpineRender'
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
data: ISpineData
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
name: 'NftItem',
|
||||
components: {
|
||||
},
|
||||
props: ['data']
|
||||
})
|
||||
export default class extends Vue {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// rect: 297x389
|
||||
$width: 14em;
|
||||
$height: 18.33em;
|
||||
.bg-img {
|
||||
width: $width;
|
||||
height: $height;
|
||||
}
|
||||
.anim-border {
|
||||
width: $width;
|
||||
height: $height;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-main-img {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
max-height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.info-div {
|
||||
background-image: url('~@/assets/main/card/name_bg.png');
|
||||
width: 100%;
|
||||
height: $height * 0.29;
|
||||
position: absolute;
|
||||
bottom: $height * 0.025;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.class-div{
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: $width*42/297;
|
||||
height: $height*42/389;
|
||||
}
|
||||
.class-div img {
|
||||
width: 100%;
|
||||
}
|
||||
.name-img {
|
||||
height: $height * 39 / 389;
|
||||
width: auto;
|
||||
position: absolute;
|
||||
right: $width * 9 / 297;
|
||||
bottom: $height * 100 / 389;
|
||||
}
|
||||
.price-label {
|
||||
color: black;
|
||||
height: $height * 29 / 389;
|
||||
font-weight: bold;
|
||||
width: $width * 145 / 297;
|
||||
background-image: url('~@/assets/main/card/price_bg.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: $width * 40 / 297;
|
||||
margin-bottom: $width * 10 / 297;
|
||||
}
|
||||
.price-label span {
|
||||
font-size: $width * 20 / 297;
|
||||
}
|
||||
.buy-icon {
|
||||
width: $width * 44 / 297;
|
||||
height: $height * 52 / 389;
|
||||
margin-left: $width * 40 / 297;
|
||||
margin-bottom: $height * 12 / 389;
|
||||
}
|
||||
|
||||
</style>
|
98
src/components/market/NftList.vue
Normal file
98
src/components/market/NftList.vue
Normal file
@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div class="card-list">
|
||||
<div class="grid">
|
||||
<nft-item v-for="c in cardList" :key="c.id" :data="c"></nft-item>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import Pagination from '@/components/market/Pagination.vue'
|
||||
import Card from '@/components/market/Card.vue'
|
||||
import NftItem from '@/components/market/NftItem.vue'
|
||||
import { ISpineData } from '@/utils/SpineRender'
|
||||
|
||||
@Component({
|
||||
name: 'NftList',
|
||||
components: {
|
||||
NftItem,
|
||||
Card,
|
||||
Pagination
|
||||
}
|
||||
})
|
||||
export default class extends Vue {
|
||||
private cardList: ISpineData[] = []
|
||||
|
||||
created() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
this.cardList.push({ id: 'hero2_10' + i, type: 0, skelName: 'n_aoi', name: 'miffy', price: '10', class: 0, repeat: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
margin-top: 2.0265em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-list .grid {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
-ms-grid-columns: (1fr)[4];
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
-webkit-column-gap: 1.875em;
|
||||
column-gap: 1.875em;
|
||||
row-gap: 1.3125em;
|
||||
}
|
||||
|
||||
.card-list .grid .card {
|
||||
height: 18em;
|
||||
width: 14em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
height: 100vh;
|
||||
-webkit-box-flex: 0;
|
||||
-ms-flex: none;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.empty {
|
||||
padding-top: 7.375em;
|
||||
}
|
||||
|
||||
.empty img {
|
||||
width: 14.625em;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.card-list .grid {
|
||||
-ms-grid-columns: (1fr)[2];
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.card-list{
|
||||
margin-top: 76px;
|
||||
padding: 26px 20px;
|
||||
};
|
||||
.card-list .grid {
|
||||
-ms-grid-columns: (1fr)[2];
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
-webkit-column-gap: 1.79em;
|
||||
column-gap: 1.79em;
|
||||
row-gap: 1.8em;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="searchResult">
|
||||
<div class="wrapper">
|
||||
<sort-select></sort-select>
|
||||
<button class="general-btn btnFilter" @click="showFilter">
|
||||
<sort-select v-if="showSort"></sort-select>
|
||||
<button class="general-btn btnFilter" v-if="showSort" @click="showFilter">
|
||||
<span>FILTERS</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -16,13 +16,19 @@ import SortSelect from '@/components/market/SortSelect.vue'
|
||||
import CardList from '@/components/market/CardList.vue'
|
||||
import ResultNo from '@/components/market/ResultNo.vue'
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
showSort?: boolean
|
||||
}
|
||||
}
|
||||
@Component({
|
||||
name: 'SearchResult',
|
||||
components: {
|
||||
ResultNo,
|
||||
CardList,
|
||||
SortSelect
|
||||
}
|
||||
},
|
||||
props: ['showSort']
|
||||
})
|
||||
export default class extends Vue {
|
||||
showFilter() {
|
||||
|
@ -10,14 +10,14 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="header-menu">
|
||||
<a class="menu-item" href="/">
|
||||
<div class="item" :class="{'active': currentTab==='presell'}">
|
||||
Official Store
|
||||
<a class="menu-item" href="/official">
|
||||
<div class="item" :class="{'active': currentTab==='official'}">
|
||||
Official Shop
|
||||
<div class="active-bottom" v-if="currentTab==='presell'"></div>
|
||||
</div
|
||||
>
|
||||
</a>
|
||||
<a class="menu-item" href="/">
|
||||
<a class="menu-item" href="/market">
|
||||
<div class="item " :class="{'active': currentTab==='market'}">
|
||||
Marketplace
|
||||
<div class="active-bottom" v-if="currentTab==='market'"></div>
|
||||
@ -37,13 +37,17 @@
|
||||
draggable="false"
|
||||
v-if="walletCollected"
|
||||
class="avatar"
|
||||
ref="avatar"
|
||||
src="https://assets.thetanarena.com/cosmetic/avatar/3.png"
|
||||
alt="avatar"
|
||||
@click="infoPanelShow=!infoPanelShow"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<top-user-info v-if="infoPanelShow && walletCollected"></top-user-info>
|
||||
<top-user-info
|
||||
v-show="infoPanelShow && walletCollected"
|
||||
v-on:close-self="onClose"
|
||||
></top-user-info>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -79,6 +83,10 @@ export default class extends Vue {
|
||||
async disconnectWallet() {
|
||||
return this.bc.disconnect()
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.infoPanelShow = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -103,7 +111,7 @@ export default class extends Vue {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 60vw;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.top-header .header-menu .menu-item {
|
||||
|
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="position dropdown anim">
|
||||
<div class="info-bg" @click="close">
|
||||
<div class="position dropdown anim" @click.stop="">
|
||||
<span class="name">SEgGQ58HRlLd</span>
|
||||
<div class="divCode">
|
||||
<span class="address">{{showAccount}}</span>
|
||||
@ -31,6 +32,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -46,6 +48,10 @@ import { Message } from 'element-ui'
|
||||
})
|
||||
export default class extends Vue {
|
||||
bc = new BlockChain();
|
||||
close(e: any) {
|
||||
console.log(e)
|
||||
this.$emit('close-self')
|
||||
}
|
||||
|
||||
get walletCollected() {
|
||||
return AppModule.walletConnected
|
||||
@ -235,7 +241,13 @@ export default class extends Vue {
|
||||
animation-name: overlay-anim;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.info-bg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import Vue from 'vue'
|
||||
import VueRouter, { RouteConfig } from 'vue-router'
|
||||
import Main from '../views/Main.vue'
|
||||
import Market from '../views/Market.vue'
|
||||
import Official from '@/views/Official.vue'
|
||||
import Item from '../views/Item.vue'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
@ -22,6 +23,11 @@ const routes: Array<RouteConfig> = [
|
||||
name: 'Market',
|
||||
component: Market
|
||||
},
|
||||
{
|
||||
path: '/official',
|
||||
name: 'Official',
|
||||
component: Official
|
||||
},
|
||||
{
|
||||
path: '/item',
|
||||
name: 'Item',
|
||||
|
@ -5,7 +5,7 @@
|
||||
<section class="root">
|
||||
<div class="container">
|
||||
<search-panel @filter-show="showFilter" :class="{'show': mobileFilterShow}"></search-panel>
|
||||
<search-result @filter-show="showFilter"></search-result>
|
||||
<search-result @filter-show="showFilter" :show-sort="true"></search-result>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
140
src/views/Official.vue
Normal file
140
src/views/Official.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<div>
|
||||
<mobile-top class="mobile-top"></mobile-top>
|
||||
<top-menu class="desk-top" :current-tab="currentTab"></top-menu>
|
||||
<section class="root">
|
||||
<div class="container">
|
||||
<nft-list></nft-list>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import SearchPanel from '@/components/market/SearchPanel.vue'
|
||||
import SearchResult from '@/components/market/SearchResult.vue'
|
||||
import TopMenu from '@/components/market/TopMenu.vue'
|
||||
import MobileTop from '@/components/market/MoileTop.vue'
|
||||
import NftList from '@/components/market/NftList.vue'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
NftList,
|
||||
MobileTop,
|
||||
SearchResult,
|
||||
SearchPanel,
|
||||
TopMenu
|
||||
}
|
||||
})
|
||||
export default class Official extends Vue {
|
||||
mobileFilterShow = false
|
||||
currentTab = 'official'
|
||||
showFilter(val: boolean) {
|
||||
this.mobileFilterShow = val
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '../scss/breakpoints.scss';
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 1440px;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.mobile-top {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@include media('<desktop') {
|
||||
.container {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
.searchPanel {
|
||||
width: 100%;
|
||||
}
|
||||
.filterTablet {
|
||||
padding-top: 40px;
|
||||
width: 100%;
|
||||
-webkit-transition: all 0.3s;
|
||||
transition: all 0.3s;
|
||||
height: auto;
|
||||
}
|
||||
.filterTablet.collapsed {
|
||||
padding-top: 0;
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
z-index: -1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.searchResult {
|
||||
padding: 2.5em 4em;
|
||||
}
|
||||
.searchResult .wrapper .btnFilter {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) and (max-width: 1439px) {
|
||||
.root {
|
||||
font-size: 11px;
|
||||
}
|
||||
.root .container {
|
||||
width: 1024px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 1023px) {
|
||||
.root {
|
||||
font-size: 20px;
|
||||
}
|
||||
.container {
|
||||
width: 768px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.root {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) and (max-width: 320px) {
|
||||
.root {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.container {
|
||||
width: 375px;
|
||||
}
|
||||
.searchResult {
|
||||
padding: 26px 20px;
|
||||
}
|
||||
.mobile-top {
|
||||
display: block;
|
||||
}
|
||||
.desk-top {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show{
|
||||
display: flex!important;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user