add presale test page

This commit is contained in:
cebgcontract 2022-02-17 13:33:51 +08:00
parent 435bc391ec
commit d4c5e97e7b
4 changed files with 374 additions and 7 deletions

View File

@ -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>

View 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>

View File

@ -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
View 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>