Skip to content

Commit

Permalink
Update Vue School summer sale banner (#1487)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicodevs committed Jul 25, 2022
1 parent 9ce152c commit 247cf9d
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 76 deletions.
55 changes: 55 additions & 0 deletions packages/docs/.vitepress/components/VueSchool/BannerCountdown.vue
@@ -0,0 +1,55 @@
<template>
<ClientOnly>
<VueCountdown
v-if="remaining"
:time="remaining"
v-slot="data">
<span
v-for="part in ['days', 'hours', 'minutes', 'seconds']"
:key="part">
{{ data[part] }}{{ part[0].toLowerCase() }}
<span
v-if="part !== 'seconds'"
class="px-1 text-xl font-bold">
:
</span>
</span>
</VueCountdown>
</ClientOnly>
</template>

<script>
import VueCountdown from '@chenfengyuan/vue-countdown'
const countdownTransform = (props) => {
Object.entries(props).forEach(([key, value]) => {
const digits = value < 10 ? `0${value}` : value
props[key] = digits
})
return props
}
export default {
components: {
VueCountdown
},
props: {
remaining: {
type: Number,
default: 0
}
},
computed: {
isVisible () {
return this.remaining > 0
}
}
}
</script>

<style scoped>
span {
color: #ff5338;
font-weight: bold;
}
</style>
173 changes: 119 additions & 54 deletions packages/docs/.vitepress/components/VueSchool/BannerTop.vue
@@ -1,5 +1,10 @@
<template>
<a id="vs" href="https://vueschool.io/sales/summer-vue/?friend=vuerouter" target="_blank" rel="noreferrer">
<a
v-if="isVisible"
id="vs"
href="https://vueschool.io/sales/summer-vue/?friend=vuerouter"
target="_blank"
rel="noreferrer">
<div class="vs-iso">
<img src="/images/vueschool/vs-iso.svg" alt="Vue School Logo">
</div>
Expand All @@ -10,22 +15,74 @@
<div class="vs-backpack">
<img src="/images/vueschool/vs-backpack.png" alt="Backpack">
</div>
<div class="vs-slogan">
<span class="vs-slogan-light">Summer Sale:</span> Get the 3 months plan for only <span style="text-decoration: line-through">$75</span> $50
<div class="vs-slogan-wrapper">
<div class="vs-slogan">
Learn Vue this summer and <span class="vs-slogan-light">save 40%</span>
</div>
<div class="vs-subline">
<span
v-if="isExtended"
:style="{ fontWeight: 'bold', marginRight: '8px' }">
Extended!
</span>
<span
v-else>
Limited time offer
</span>
<BannerCountdown
v-bind="{ remaining }" />
</div>
</div>
<div class="vs-button">
Get 33% OFF
Get Offer
</div>
</div>
<div
id="vs-close"
class="vs-close"
@click.stop.prevent="$emit('close')">
@click.stop.prevent="close">
<img src="/images/vueschool/close.svg" alt="Close">
</div>
</a>
</template>

<script>
import BannerCountdown from './BannerCountdown.vue'
export default {
components: {
BannerCountdown
},
data () {
return {
isActive: null,
isExtended: null,
isVisible: false,
remaining: 0
}
},
mounted () {
const now = new Date()
const extension = new Date('2022-07-27T00:00:00+02:00')
const end = new Date('2022-07-29T00:00:00+02:00')
this.isActive = now < end
this.isExtended = now > extension && now < end
this.remaining = (this.isExtended ? end : extension) - now
this.isVisible = !localStorage.getItem('VS_SUMMER_22') && this.remaining > 0
if (this.isVisible) document.body.classList.add('has-top-banner')
},
methods: {
close () {
this.isVisible = false
document.body.classList.remove('has-top-banner')
localStorage.setItem('VS_SUMMER_22', 1)
}
}
}
</script>

<style>
#vs {
align-items: center;
Expand All @@ -40,104 +97,120 @@
right: 0;
top: 0;
z-index: 100;
height: 3.125rem;
height: 5rem;
display: flex;
}
#vs:hover {
text-decoration: none;
}
@media (min-width: 680px) {
#vs {
height: 5rem;
}
}
#vs:hover .vs-core .vs-button {
background: #f22606;
}
#vs .vs-iso {
position: absolute;
left: 20px;
height: 26px;
display: none;
}
#vs .vs-iso img {
height: 26px;
}
@media (min-width: 680px) {
#vs .vs-iso {
left: 40px;
height: 40px;
display: inline-block;
}
#vs .vs-iso img {
height: 40px;
}
}
@media (min-width: 900px) {
#vs .vs-iso {
display: none;
}
}
#vs .vs-logo {
position: absolute;
display: none;
left: 40px;
}
@media (min-width: 900px) {
#vs .vs-logo {
display: block;
}
}
#vs .vs-core {
display: flex;
align-items: center;
}
#vs .vs-core .vs-backpack {
margin-right: 14px;
margin-right: 26px;
}
#vs .vs-core .vs-backpack img {
height: 38px;
height: 44px;
}
@media (min-width: 900px) {
#vs .vs-core .vs-backpack img {
height: 50px;
}
}
@media (min-width: 900px) {
#vs .vs-core .vs-backpack img {
height: 74px;
}
#vs .vs-core .vs-slogan-wrapper {
margin-right: 26px;
}
#vs .vs-core .vs-slogan {
color: #FFF;
font-weight: bold;
font-size: 14px;
margin-right: 26px;
font-size: 16px;
text-align: center;
}
@media (min-width: 680px) {
#vs .vs-core .vs-slogan {
margin-right: 0;
font-size: 16px;
}
}
@media (min-width: 900px) {
#vs .vs-core .vs-slogan {
font-size: 20px;
font-size: 18px;
}
}
#vs .vs-core .vs-slogan > .vs-slogan-light {
color: #ff5338;
color: #00b5ff;
display: block;
text-align: left;
}
#vs .vs-core .vs-slogan-wrapper .vs-subline {
color: #FFF;
text-align: center;
font-size: 12px;
}
@media (min-width: 680px) {
#vs .vs-core .vs-slogan-wrapper .vs-subline {
font-size: 16px;
}
}
@media (min-width: 900px) {
#vs .vs-core .vs-slogan > .vs-slogan-light {
text-align: center;
display: inline;
}
}
#vs .vs-core .vs-button {
margin-left: 43px;
color: #fff;
padding: 13px 24px;
border-radius: 40px;
Expand All @@ -146,52 +219,44 @@
font-weight: bold;
text-transform: uppercase;
}
@media (min-width: 680px) {
#vs .vs-core .vs-button {
display: inline-block;
}
}
#vs .vs-close {
right: 10px;
position: absolute;
padding: 10px;
}
@media (min-width: 680px) {
#vs .vs-close {
right: 20px;
}
}
#vs .vs-close:hover {
color: #56d8ff;
}
/************************************/
.main-container.has-top-banner #vs {
display: flex;
}
.main-container.has-top-banner {
margin-top: 3.125rem;
}
.main-container.has-top-banner .nav-bar {
margin-top: 3.125rem;
.has-top-banner {
margin-top: 5rem;
}
.main-container.has-top-banner .sidebar {
margin-top: 3.125rem;
.has-top-banner .nav-bar {
margin-top: 5rem;
}
.main-container.has-top-banner .page {
margin-top: 3.125rem;
.has-top-banner .sidebar {
margin-top: 5rem;
}
@media (min-width: 680px) {
.main-container.has-top-banner {
margin-top: 5rem;
}
.main-container.has-top-banner .nav-bar {
margin-top: 5rem;
}
.main-container.has-top-banner .sidebar {
margin-top: 5rem;
}
.main-container.has-top-banner .page {
margin-top: 5rem;
}
.has-top-banner .page {
margin-top: 5rem;
}
</style>
24 changes: 3 additions & 21 deletions packages/docs/.vitepress/theme/Layout.vue
@@ -1,12 +1,6 @@
<template>
<div
class="main-container"
:class="{ 'has-top-banner': showTopBanner }"
>
<BannerTop
v-if="showTopBanner"
@close="closeBannerTop"
/>
<div class="main-container">
<BannerTop />
<ParentLayout>
<template #sidebar-top>
<div class="sponsors sponsors-top">
Expand Down Expand Up @@ -68,19 +62,7 @@ export default {
},
data() {
return {
sponsors,
showTopBanner: false
}
},
mounted () {
const now = new Date()
const end = new Date('2022-07-23T00:00:00+02:00')
this.showTopBanner = !localStorage.getItem('VS_SUMMER_22') && (now < end)
},
methods: {
closeBannerTop () {
this.showTopBanner = false
localStorage.setItem('VS_SUMMER_22', 1)
sponsors
}
}
}
Expand Down

0 comments on commit 247cf9d

Please sign in to comment.