]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
Update Vue School summer sale banner (#1487)
authorNico Devs <3766839+nicodevs@users.noreply.github.com>
Mon, 25 Jul 2022 16:14:31 +0000 (13:14 -0300)
committerGitHub <noreply@github.com>
Mon, 25 Jul 2022 16:14:31 +0000 (18:14 +0200)
packages/docs/.vitepress/components/VueSchool/BannerCountdown.vue [new file with mode: 0644]
packages/docs/.vitepress/components/VueSchool/BannerTop.vue
packages/docs/.vitepress/theme/Layout.vue
packages/docs/package.json
pnpm-lock.yaml

diff --git a/packages/docs/.vitepress/components/VueSchool/BannerCountdown.vue b/packages/docs/.vitepress/components/VueSchool/BannerCountdown.vue
new file mode 100644 (file)
index 0000000..5b57be1
--- /dev/null
@@ -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>
index 1a70e6acac96a943507cd058139685a3789af123..a187640dc9aaf03b9e603a8cb59575fc65c47824 100644 (file)
@@ -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>
       <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;
   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;
   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>
index f9a52ffa9d2bf2c8540dba651fdcd1a0f3357b9a..eeebfc4264fb96a07402aec17914e2dd58270a17 100644 (file)
@@ -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">
@@ -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
     }
   }
 }
index ab0223b009411a054c30b1eeaaedee906970332c..ad2b4ae31c440f8cfb692265ab587664fbbb54f0 100644 (file)
@@ -8,6 +8,7 @@
     "docs:build": "vitepress build ."
   },
   "dependencies": {
+    "@chenfengyuan/vue-countdown": "2",
     "vitepress": "^0.20.0"
   }
 }
index 2d0f31f2e8da7e2736f9a50544c5a103fea19633..4086faf7d402d3a24019c31d8d9cb700f51af69c 100644 (file)
@@ -1,4 +1,4 @@
-lockfileVersion: 5.4
+lockfileVersion: 5.3
 
 importers:
 
@@ -32,8 +32,10 @@ importers:
 
   packages/docs:
     specifiers:
+      '@chenfengyuan/vue-countdown': '2'
       vitepress: ^0.20.0
     dependencies:
+      '@chenfengyuan/vue-countdown': 2.0.0
       vitepress: 0.20.10
 
   packages/playground:
@@ -552,6 +554,12 @@ packages:
     resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
     dev: true
 
+  /@chenfengyuan/vue-countdown/2.0.0:
+    resolution: {integrity: sha512-uZQBuajO9Jp5y5Hh5/C61qZw5oQXv3Cgd0FWO4j22SmwY7pzEHC7A/liobHjHeLiQH9WKVEhyOzmIZ2a4WSXhQ==}
+    peerDependencies:
+      vue: ^3.0.0
+    dev: false
+
   /@docsearch/css/3.1.0:
     resolution: {integrity: sha512-bh5IskwkkodbvC0FzSg1AxMykfDl95hebEKwxNoq4e5QaGzOXSBgW8+jnMFZ7JU4sTBiB04vZWoUSzNrPboLZA==}
     dev: false