Skip to content

Commit 3a939c9

Browse files
authored
Docs: Update Free Weekend Vue School banner (#1566)
1 parent e40cd0b commit 3a939c9

File tree

12 files changed

+440
-832
lines changed

12 files changed

+440
-832
lines changed
Lines changed: 397 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
<template>
2+
<a
3+
id="vs-top"
4+
v-if="isVisible"
5+
:href="`https://vueschool.io${activeBanner.link}?friend=vuerouter&utm_source=vuerouter&utm_medium=website&utm_campaign=affiliate&utm_content=top_banner`"
6+
:class="activeBanner.assets">
7+
<div class="vs-background-wrapper">
8+
<div class="vs-logo" />
9+
<div class="vs-core">
10+
<div class="vs-slogan-wrapper">
11+
<div class="vs-slogan" v-html="activeBanner.title" />
12+
<div class="vs-subline" v-html="activeBanner.subtitle" />
13+
<BannerTopCountdownMobile
14+
v-if="activePhase.hasCountdown"
15+
v-bind="{ remaining: activePhase.remaining, countdownTransformDaysToHours }" />
16+
</div>
17+
<BannerTopCountdown
18+
v-if="activePhase.hasCountdown"
19+
v-bind="{ remaining: activePhase.remaining, countdownTransformDaysToHours }" />
20+
<div class="vs-button-wrapper">
21+
<div class="vs-button">
22+
{{ activeBanner.cta }}
23+
</div>
24+
</div>
25+
</div>
26+
<div
27+
class="vs-close"
28+
@click.prevent.stop="close">
29+
<img src="https://vueschool.io/images/close.svg" alt="Close">
30+
</div>
31+
</div>
32+
</a>
33+
</template>
34+
35+
<script>
36+
import BannerTopCountdown from './BannerTopCountdown.vue'
37+
import BannerTopCountdownMobile from './BannerTopCountdownMobile.vue'
38+
39+
const phases = [
40+
{
41+
banner: {
42+
assets: "FREE_WEEKEND",
43+
cta: "JOIN FOR FREE",
44+
link: "/free-weekend",
45+
static: "FREE_WEEKEND",
46+
subtitle: "Get Access to ALL Vue School premium courses",
47+
title: "Free Weekend 1st & 2nd of October"
48+
},
49+
ends: "2022-09-30T23:59:59+02:00",
50+
hasCountdown: false,
51+
id: "FREE_WEEKEND_LOBBY",
52+
isExtended: false
53+
},
54+
{
55+
banner: {
56+
assets: "FREE_WEEKEND",
57+
cta: "WATCH FOR FREE",
58+
link: "/free-weekend",
59+
static: "FREE_WEEKEND_LIVE",
60+
subtitle: "Get Access to ALL Vue School premium courses",
61+
title: "Free Weekend <strong>NOW LIVE</strong>"
62+
},
63+
ends: "2022-10-02T23:59:59+02:00",
64+
hasCountdown: false,
65+
id: "FREE_WEEKEND_LIVE",
66+
isExtended: false
67+
},
68+
{
69+
banner: {
70+
assets: "LEVELUP2022",
71+
cta: "GET OFFER",
72+
link: "/sales/levelup2022",
73+
static: "LEVELUP2022",
74+
subtitle: "Access 800+ lessons including the Vue.js 3 Masterclass",
75+
title: "<strong>Get 45%</strong> off at Vue School today"
76+
},
77+
ends: "2022-10-04T23:59:59+02:00",
78+
hasCountdown: true,
79+
id: "LEVELUP2022",
80+
isExtended: false
81+
},
82+
{
83+
banner: {
84+
assets: "LEVELUP2022",
85+
cta: "GET OFFER",
86+
link: "/sales/levelup2022",
87+
static: "LEVELUP2022",
88+
subtitle: "Extended! Access 800+ lessons including the Vue.js 3 Masterclass",
89+
title: "<strong>Get 45%</strong> off at Vue School today"
90+
},
91+
ends: "2022-10-06T23:59:59+02:00",
92+
hasCountdown: true,
93+
id: "LEVELUP2022_EXTENDED",
94+
isExtended: true
95+
}
96+
]
97+
98+
export default {
99+
components: {
100+
BannerTopCountdown,
101+
BannerTopCountdownMobile
102+
},
103+
data () {
104+
const now = new Date()
105+
return {
106+
isVisible: false,
107+
now
108+
}
109+
},
110+
computed: {
111+
phases () {
112+
return phases.map(phase => ({ ...phase, remaining: new Date(phase.ends) - this.now }))
113+
},
114+
activePhase () {
115+
return this.phases.find(phase => phase.remaining > 0)
116+
},
117+
activeBanner () {
118+
return this.activePhase.banner
119+
}
120+
},
121+
mounted () {
122+
this.isVisible = !localStorage.getItem('VS_FREE_WEEKEND') && Boolean(this.activePhase)
123+
if (this.isVisible) document.body.classList.add('has-top-banner')
124+
},
125+
methods: {
126+
countdownTransformDaysToHours (props) {
127+
if (props.days) {
128+
props.hours = props.hours + (props.days * 24)
129+
props.days = 0
130+
}
131+
132+
Object.entries(props).forEach(([key, value]) => {
133+
const digits = value < 10 ? `0${value}` : value
134+
props[key] = digits
135+
})
136+
return props
137+
},
138+
close () {
139+
this.isVisible = false
140+
document.body.classList.remove('has-top-banner')
141+
localStorage.setItem('VS_FREE_WEEKEND', 1)
142+
}
143+
}
144+
}
145+
</script>
146+
147+
<style>
148+
#vs-top {
149+
display: block;
150+
box-sizing: border-box;
151+
height: 72px;
152+
position: fixed;
153+
top: 0;
154+
left: 0;
155+
right: 0;
156+
z-index: 100;
157+
}
158+
159+
#vs-top .vs-background-wrapper {
160+
align-items: center;
161+
justify-content: center;
162+
display: flex;
163+
padding: 0 10px;
164+
height: 100%;
165+
width: 100%;
166+
}
167+
168+
#vs-top:hover {
169+
text-decoration: none;
170+
}
171+
172+
#vs-top:hover .vs-core .vs-button {
173+
background-image: linear-gradient(to bottom, #5ccc45, #419E2D), linear-gradient(to bottom, #388f26, #50b83b);
174+
}
175+
176+
#vs-top .vs-logo {
177+
position: absolute;
178+
left: 10px;
179+
width: 36px;
180+
height: 42px;
181+
background-size: contain;
182+
background-position: center;
183+
background-repeat: no-repeat;
184+
}
185+
186+
#vs-top .vs-core {
187+
display: flex;
188+
align-items: center;
189+
width: 288px;
190+
}
191+
192+
#vs-top .vs-core .vs-slogan-wrapper {
193+
text-align: center;
194+
width: 184px;
195+
margin: 0 auto;
196+
}
197+
198+
#vs-top .vs-core .vs-slogan {
199+
font-weight: bold;
200+
font-size: 12px;
201+
font-family: 'Roboto', Arial, sans-serif;
202+
}
203+
204+
#vs-top .vs-core .vs-subline {
205+
font-size: 10px;
206+
font-family: 'Roboto', Arial, sans-serif;
207+
text-align: center;
208+
}
209+
210+
#vs-top .vs-core .vs-button-wrapper {
211+
padding: 2px;
212+
background-image: linear-gradient(to bottom, #388f26, #50b83b);
213+
border-radius: 60px;
214+
overflow: hidden;
215+
}
216+
217+
#vs-top .vs-core .vs-button {
218+
border-radius: 60px;
219+
color: #FFF;
220+
padding: 8px 6px;
221+
background-image: linear-gradient(to bottom, #5ccc45, #368c24), linear-gradient(to bottom, #388f26, #50b83b);
222+
font-weight: bold;
223+
text-transform: uppercase;
224+
text-align: center;
225+
font-size: 10px;
226+
letter-spacing: 0.3px;
227+
white-space: nowrap;
228+
}
229+
230+
#vs-top .vs-close {
231+
right: 0;
232+
position: absolute;
233+
padding: 10px;
234+
}
235+
236+
#vs-top .vs-close:hover {
237+
color: #56d8ff;
238+
}
239+
240+
@media (min-width: 680px) {
241+
#vs-top .vs-core {
242+
width: auto;
243+
}
244+
245+
#vs-top .vs-core .vs-slogan-wrapper {
246+
margin: 0 12px 0 0;
247+
width: 268px;
248+
}
249+
250+
#vs-top .vs-core .vs-slogan {
251+
font-size: 17px;
252+
}
253+
254+
#vs-top .vs-core .vs-subline {
255+
font-size: 12px;
256+
margin-top: 4px;
257+
}
258+
259+
#vs-top .vs-core .vs-button {
260+
font-size: 13px;
261+
padding: 8px 15px;
262+
}
263+
}
264+
265+
@media (min-width: 1280px) {
266+
#vs-top .vs-logo {
267+
left: 20px;
268+
width: 104px;
269+
}
270+
271+
#vs-top .vs-core {
272+
margin-right: 0;
273+
}
274+
275+
#vs-top .vs-core .vs-slogan-wrapper {
276+
width: auto;
277+
}
278+
279+
#vs-top .vs-core .vs-subline {
280+
font-size: 15px;
281+
}
282+
}
283+
284+
/* FREE_WEEKEND
285+
******************************************/
286+
287+
#vs-top.FREE_WEEKEND {
288+
color: #FFF;
289+
background: linear-gradient(to left, #161a35, #283065);
290+
}
291+
292+
#vs-top.FREE_WEEKEND .vs-logo {
293+
background-image: url(https://vueschool.io/images/mark-vueschool-white.svg);
294+
}
295+
296+
#vs-top.FREE_WEEKEND .vs-core .vs-slogan {
297+
color: #fff;
298+
}
299+
300+
#vs-top.FREE_WEEKEND .vs-core .vs-slogan strong {
301+
color: #ff2556;
302+
}
303+
304+
#vs-top.FREE_WEEKEND .vs-core .vs-subline {
305+
color: #c6cdf7;
306+
}
307+
308+
#vs-top.FREE_WEEKEND .vs-background-wrapper {
309+
background-image: url(https://vueschool.io/images/banners/assets/FREE_WEEKEND/bg-mobile.png);
310+
background-repeat: no-repeat;
311+
background-size: cover;
312+
background-position: top right;
313+
}
314+
315+
@media (min-width: 680px) {
316+
#vs-top.FREE_WEEKEND .vs-background-wrapper {
317+
background-image: url(https://vueschool.io/images/banners/assets/FREE_WEEKEND/bg-tablet.svg);
318+
}
319+
}
320+
321+
@media (min-width: 1280px) {
322+
#vs-top.FREE_WEEKEND .vs-logo {
323+
background-image: url(https://vueschool.io/images/icons/logo-white.svg);
324+
}
325+
326+
#vs-top.FREE_WEEKEND .vs-background-wrapper {
327+
background-image: url(https://vueschool.io/images/banners/assets/FREE_WEEKEND/bg-desktop.svg);
328+
background-position: top right -60px;
329+
}
330+
}
331+
332+
/* LEVELUP2022
333+
******************************************/
334+
335+
#vs-top.LEVELUP2022 {
336+
color: #121733;
337+
background: #EEF5FF;
338+
}
339+
340+
#vs-top.LEVELUP2022 .vs-logo {
341+
background-image: url(https://vueschool.io/images/mark-vueschool.svg);
342+
}
343+
344+
#vs-top.LEVELUP2022 .vs-core .vs-slogan {
345+
color: #121733;
346+
}
347+
348+
#vs-top.LEVELUP2022 .vs-core .vs-slogan strong {
349+
color: #48aa34;
350+
}
351+
352+
#vs-top.LEVELUP2022 .vs-core .vs-subline {
353+
color: #394170;
354+
}
355+
356+
#vs-top.LEVELUP2022 .vs-core .vs-subline strong {
357+
color: #48aa34;
358+
}
359+
360+
#vs-top.LEVELUP2022 .vs-background-wrapper {
361+
background-image: url(https://vueschool.io/images/banners/assets/LEVELUP2022/bg-mobile.png);
362+
background-repeat: no-repeat;
363+
background-size: cover;
364+
background-position: top right;
365+
}
366+
367+
@media (min-width: 680px) {
368+
#vs-top.LEVELUP2022 .vs-background-wrapper {
369+
background-image: url(https://vueschool.io/images/banners/assets/LEVELUP2022/bg-tablet.png);
370+
}
371+
}
372+
373+
@media (min-width: 1280px) {
374+
#vs-top.LEVELUP2022 .vs-logo {
375+
background-image: url(https://vueschool.io/images/icons/logo.svg);
376+
}
377+
378+
#vs-top.LEVELUP2022 .vs-background-wrapper {
379+
background-image:
380+
url(https://vueschool.io/images/banners/assets/LEVELUP2022/bg-desktop-left.png),
381+
url(https://vueschool.io/images/banners/assets/LEVELUP2022/bg-desktop-right.png);
382+
background-position:
383+
top left -120px,
384+
top right -120px;
385+
background-size: contain;
386+
background-repeat: no-repeat;
387+
}
388+
}
389+
390+
@media (min-width: 1536px) {
391+
#vs-top.LEVELUP2022 .vs-background-wrapper {
392+
background-position:
393+
top left,
394+
top right;
395+
}
396+
}
397+
</style>

0 commit comments

Comments
 (0)