add presale test page
This commit is contained in:
parent
435bc391ec
commit
d4c5e97e7b
@ -10,6 +10,11 @@
|
||||
</div>
|
||||
<card-scroller :heros="heroDatas" :presale-status="presaleStatus" class="card-scroller"></card-scroller>
|
||||
<div class="count-label">{{numberRest}}/{{numberTotal}}</div>
|
||||
<div class="order-status" v-show="showOrderStatus">
|
||||
<el-tooltip class="item" effect="light" content="Transaction in progress" placement="right">
|
||||
<time-loader></time-loader>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@ -23,10 +28,12 @@ import { secs2str } from '@/utils/time.util'
|
||||
import { EventBus, PRESALE_BEGIN, PRESALE_ERROR, PRESALE_ORDER_GET, PRESALE_SUCCESS } from '@/utils/event-bus'
|
||||
import { Loading } from 'element-ui'
|
||||
import { ElLoadingComponent } from 'element-ui/types/loading'
|
||||
import TimeLoader from '@/components/main/TimeLoader.vue'
|
||||
|
||||
@Component({
|
||||
name: 'NftSection',
|
||||
components: {
|
||||
TimeLoader,
|
||||
CardScroller
|
||||
|
||||
}
|
||||
@ -44,11 +51,18 @@ export default class extends Vue {
|
||||
timer: any = null
|
||||
orderTimer: any = null
|
||||
loadingInstance: ElLoadingComponent
|
||||
showOrderStatus = false
|
||||
historyOrderId: string | null = ''
|
||||
|
||||
created() {
|
||||
this.fetchData()
|
||||
this.subscribeToEvents()
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.checkOrderHistory()
|
||||
}
|
||||
|
||||
unmounted() {
|
||||
this.removeEvents()
|
||||
}
|
||||
@ -57,6 +71,7 @@ export default class extends Vue {
|
||||
private accountChange() {
|
||||
if (this.accountId) {
|
||||
this.getPresaleInfo()
|
||||
this.checkOrderHistory()
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,6 +89,13 @@ export default class extends Vue {
|
||||
await this.getPresaleInfo()
|
||||
}
|
||||
|
||||
checkOrderHistory() {
|
||||
const historyOrderId = localStorage.getItem('tmp_presale_order_id')
|
||||
if (historyOrderId && this.accountId) {
|
||||
this.beginTraceOrderStatus(historyOrderId)
|
||||
}
|
||||
}
|
||||
|
||||
subscribeToEvents() {
|
||||
EventBus.$on(PRESALE_BEGIN, this.onPresaleBegin.bind(this))
|
||||
EventBus.$on(PRESALE_SUCCESS, this.onPresaleSuccess.bind(this))
|
||||
@ -95,23 +117,28 @@ export default class extends Vue {
|
||||
|
||||
onOrderIDGeted(orderId: string) {
|
||||
console.log('order id:', orderId)
|
||||
this.$alert('Transaction in progress', 'We will notify you after confirmation', { type: 'info', confirmButtonText: 'OK' })
|
||||
this.beginTraceOrderStatus(orderId)
|
||||
}
|
||||
|
||||
onPresaleError(res: any) {
|
||||
console.log('presale error: ', res)
|
||||
this.loadingInstance.close()
|
||||
this.showOrderStatus = false
|
||||
this.loadingInstance?.close()
|
||||
this.$alert('Some error when process presale', 'Buy Failed', { type: 'error', confirmButtonText: 'OK' })
|
||||
}
|
||||
|
||||
async onPresaleSuccess(res: any) {
|
||||
console.log('presale success', res)
|
||||
this.resetTmpOrderId()
|
||||
this.showOrderStatus = false
|
||||
this.$alert('Congratulations', 'Buy Success', { type: 'success', confirmButtonText: 'OK' })
|
||||
await this.getPresaleInfo()
|
||||
}
|
||||
|
||||
beginTraceOrderStatus(orderId: string) {
|
||||
this.showOrderStatus = true
|
||||
this.loadingInstance?.close()
|
||||
this.orderTimer = setInterval(() => {
|
||||
this.getOrderStatus(orderId)
|
||||
}, 1000)
|
||||
@ -123,7 +150,7 @@ export default class extends Vue {
|
||||
this.orderTimer = null
|
||||
}
|
||||
localStorage.removeItem('tmp_presale_order_id')
|
||||
this.loadingInstance.close()
|
||||
this.loadingInstance?.close()
|
||||
}
|
||||
|
||||
async getOrderStatus(orderId: string) {
|
||||
@ -334,5 +361,19 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
.order-status {
|
||||
transform: scale(0.3);
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
border-radius: 110px;
|
||||
background: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transform-origin: top;
|
||||
position: fixed;
|
||||
left: 100px;
|
||||
top: 100px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
266
src/components/main/TimeLoader.vue
Normal file
266
src/components/main/TimeLoader.vue
Normal file
@ -0,0 +1,266 @@
|
||||
<template>
|
||||
<div class="loader">
|
||||
<div class="timerWrap">
|
||||
<svg version="1.1" viewBox="131.623 175.5 120 160" preserveAspectRatio="xMinYMin meet" class="timer">
|
||||
<path fill="#FFFFFF" d="M212.922,255.45l36.855-64.492c1.742-3.069,1.742-6.836-0.037-9.896c-1.783-3.06-5.037-4.938-8.581-4.938
|
||||
h-99.158c-3.524,0-6.797,1.878-8.569,4.938c-1.773,3.06-1.792,6.827-0.03,9.896l36.846,64.491l-36.845,64.492
|
||||
c-1.762,3.068-1.743,6.836,0.03,9.896c1.772,3.061,5.044,4.938,8.569,4.938h99.158c3.544,0,6.798-1.878,8.581-4.938
|
||||
c1.779-3.06,1.779-6.827,0.037-9.896L212.922,255.45z M142.001,324.86l39.664-69.41l-39.664-69.41h99.158l-39.663,69.41
|
||||
l39.663,69.41H142.001z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
|
||||
@Component({
|
||||
name: 'TimeLoader',
|
||||
components: {
|
||||
|
||||
}
|
||||
})
|
||||
export default class extends Vue {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@-webkit-keyframes timerRotate {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(-180deg);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes timerRotate {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(-180deg);
|
||||
}
|
||||
}
|
||||
@-ms-keyframes timerRotate {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(-180deg);
|
||||
}
|
||||
}
|
||||
@keyframes timerRotate {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(-180deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes bottomFill {
|
||||
0% {
|
||||
border-bottom-width: 0px;
|
||||
}
|
||||
50% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
100% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes bottomFill {
|
||||
0% {
|
||||
border-bottom-width: 0px;
|
||||
}
|
||||
50% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
100% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes bottomFill {
|
||||
0% {
|
||||
border-bottom-width: 0px;
|
||||
}
|
||||
50% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
100% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
}
|
||||
@keyframes bottomFill {
|
||||
0% {
|
||||
border-bottom-width: 0px;
|
||||
}
|
||||
50% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
100% {
|
||||
border-bottom-width: 60px;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes topEmpty {
|
||||
0% {
|
||||
top: 19px;
|
||||
border-top-width: 60px;
|
||||
border-left-width: 35px;
|
||||
border-right-width: 35px;
|
||||
}
|
||||
50% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
100% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes topEmpty {
|
||||
0% {
|
||||
top: 19px;
|
||||
border-top-width: 60px;
|
||||
border-left-width: 35px;
|
||||
border-right-width: 35px;
|
||||
}
|
||||
50% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
100% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes topEmpty {
|
||||
0% {
|
||||
top: 19px;
|
||||
border-top-width: 60px;
|
||||
border-left-width: 35px;
|
||||
border-right-width: 35px;
|
||||
}
|
||||
50% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
100% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
}
|
||||
@keyframes topEmpty {
|
||||
0% {
|
||||
top: 19px;
|
||||
border-top-width: 60px;
|
||||
border-left-width: 35px;
|
||||
border-right-width: 35px;
|
||||
}
|
||||
50% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
100% {
|
||||
top: 80px;
|
||||
border-top-width: 0px;
|
||||
border-left-width: 0px;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
}
|
||||
.loader {
|
||||
width: 50%;
|
||||
height: 200px;
|
||||
float: left;
|
||||
-webkit-transform: translateZ(0);
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
-webkit-perspective: 1000;
|
||||
margin-top: -20px;
|
||||
}
|
||||
.loader .timerWrap {
|
||||
position: relative;
|
||||
animation: timerRotate 1s infinite ease;
|
||||
-webkit-animation: timerRotate 1s infinite ease;
|
||||
-moz-animation: timerRotate 1s infinite ease;
|
||||
-ms-animation: timerRotate 1s infinite ease;
|
||||
width: 120px;
|
||||
height: 160px;
|
||||
margin: auto;
|
||||
top: 40px;
|
||||
}
|
||||
.loader .timerWrap:before {
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 60px 35px 0 35px;
|
||||
border-color: #e08f24 transparent transparent transparent;
|
||||
position: absolute;
|
||||
top: 19px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
animation: topEmpty 1s infinite ease;
|
||||
-webkit-animation: topEmpty 1s infinite ease;
|
||||
-moz-animation: topEmpty 1s infinite ease;
|
||||
-ms-animation: topEmpty 1s infinite ease;
|
||||
}
|
||||
.loader .timerWrap:after {
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 0 35px 60px 35px;
|
||||
border-color: transparent transparent #e08f24 transparent;
|
||||
position: absolute;
|
||||
bottom: 19px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
animation: bottomFill 1s infinite ease;
|
||||
-webkit-animation: bottomFill 1s infinite ease;
|
||||
-moz-animation: bottomFill 1s infinite ease;
|
||||
-ms-animation: bottomFill 1s infinite ease;
|
||||
}
|
||||
.loader .timerWrap .timer {
|
||||
width: 120px;
|
||||
max-width: 100%;
|
||||
height: 160px;
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.loader .timerWrap .timer path {
|
||||
fill: #3f6b9d;
|
||||
}
|
||||
|
||||
</style>
|
@ -6,6 +6,7 @@ import Official from '@/views/Official.vue'
|
||||
import Item from '../views/Item.vue'
|
||||
import MyNft from '@/views/MyNft.vue'
|
||||
import Index from '@/views/Index.vue'
|
||||
import Presale from '@/views/Presale.vue'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
@ -30,6 +31,16 @@ const routes: Array<RouteConfig> = [
|
||||
name: 'Official',
|
||||
component: Official
|
||||
},
|
||||
{
|
||||
path: '/old',
|
||||
name: 'Old',
|
||||
component: Main
|
||||
},
|
||||
{
|
||||
path: '/presale',
|
||||
name: 'Presale',
|
||||
component: Presale
|
||||
},
|
||||
{
|
||||
path: '/mynft',
|
||||
name: 'MyNft',
|
||||
@ -48,11 +59,6 @@ const routes: Array<RouteConfig> = [
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "about" */ '../views/About.vue')
|
||||
},
|
||||
{
|
||||
path: '/index',
|
||||
name: 'Index',
|
||||
component: Index
|
||||
}
|
||||
]
|
||||
|
||||
|
54
src/views/Presale.vue
Normal file
54
src/views/Presale.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div>
|
||||
<main-header
|
||||
:current-section="section"
|
||||
@section-change="topMenuClicked"
|
||||
></main-header>
|
||||
<main id="fullpage">
|
||||
<nft-section></nft-section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import MainHeader from '@/components/main/MainHeader.vue'
|
||||
import NftSection from '@/components/main/NftSection.vue'
|
||||
@Component({
|
||||
name: 'Presale',
|
||||
components: {
|
||||
NftSection,
|
||||
MainHeader
|
||||
}
|
||||
})
|
||||
export default class extends Vue {
|
||||
private section = 'nft'
|
||||
private topMenuClicked(section: string) {
|
||||
this.section = section
|
||||
console.log('topMenuClicked: ', section)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
section {
|
||||
height: 100vh;
|
||||
filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale')";
|
||||
-moz-background-size:100% 100%;
|
||||
background-size:100% 100%;
|
||||
}
|
||||
#fullpage{
|
||||
max-width: 1920px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
section{
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
#fullpage{
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user