Skip to content

Commit 49aaa80

Browse files
authored
Vuemastery free weekend banner nov 2023 (#2561)
1 parent 7b9eb9c commit 49aaa80

File tree

6 files changed

+955
-1
lines changed

6 files changed

+955
-1
lines changed
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
<template>
2+
<div class="vuemastery-banner-wrapper" role="banner" v-if="isVisible">
3+
<div
4+
:class="{ 'show-flash': showFlash }"
5+
class="vuemastery-background-dim"
6+
ref="vuemastery-banner-flash"
7+
></div>
8+
<a
9+
id="vm-free-weekend"
10+
href="https://www.vuemastery.com/free-weekend"
11+
target="_blank"
12+
>
13+
<img
14+
id="vm-logo-full"
15+
src="/vuemastery/vuemastery-white.svg"
16+
alt="vuemastery"
17+
/>
18+
<img
19+
id="vm-logo-small"
20+
src="https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2Fvue-mastery-logo-small.png?alt=media&token=941fcc3a-2b6f-40e9-b4c8-56b3890da108"
21+
alt="vuemastery"
22+
/>
23+
<div class="vm-free-weekend-wrapper">
24+
<div class="vm-free-weekend-content">
25+
<h1 class="vm-free-weekend-title">
26+
FREE WEEKEND <span>NOV 10-12</span>
27+
</h1>
28+
<p class="vm-free-weekend-sub">
29+
Watch all Vue Mastery courses free
30+
</p>
31+
</div>
32+
<button id="vm-banner-cta">Get Access</button>
33+
</div>
34+
<button id="vm-banner-close" @click.prevent="closeBanner">
35+
<VTIconPlus class="close" />
36+
</button>
37+
</a>
38+
</div>
39+
</template>
40+
41+
<script setup lang="ts">
42+
import { ref, onMounted } from 'vue'
43+
import { VTIconPlus } from '@vue/theme'
44+
45+
const isVisible = ref<Boolean>(true)
46+
const showFlash = ref<Boolean>(false)
47+
const nameStorage = 'VUEMASTERY-BANNER--FREE-WEEKEND-MARCH-2023'
48+
49+
const closeBanner = () => {
50+
// Hide the banner
51+
isVisible.value = false
52+
// Save action in the local storage
53+
localStorage.setItem(nameStorage, String(true))
54+
document.documentElement.classList.remove('vuemastery-menu-fixed')
55+
}
56+
57+
onMounted(() => {
58+
isVisible.value = !localStorage.getItem(nameStorage)
59+
if (isVisible.value) {
60+
document.documentElement.classList.add('vuemastery-menu-fixed')
61+
setTimeout(() => {
62+
showFlash.value = true
63+
}, 2000)
64+
}
65+
})
66+
</script>
67+
<style scoped>
68+
.vuemastery-banner-wrapper {
69+
position: fixed;
70+
top: 0;
71+
bottom: 0;
72+
left: 0;
73+
right: 0;
74+
z-index: 61;
75+
width: 100%;
76+
height: 100%;
77+
max-height: 70px;
78+
background: linear-gradient(45deg, #0a2b4e, #835ec2);
79+
background-size: 110%;
80+
background-position: 50% 50%;
81+
overflow: hidden;
82+
padding: 12px;
83+
margin: 0;
84+
transition: background-size 0.25s cubic-bezier(0.39, 0.575, 0.565, 1);
85+
}
86+
87+
.vuemastery-banner-wrapper:hover {
88+
background-size: 100%;
89+
}
90+
91+
.vuemastery-banner-wrapper:before {
92+
content: '';
93+
background: url(/vuemastery/background-bubbles-vuemastery.svg) left
94+
center no-repeat;
95+
background-size: cover;
96+
position: absolute;
97+
top: 0;
98+
bottom: 0;
99+
left: 0;
100+
right: 0;
101+
transition: all 0.3s ease-out 0.1s;
102+
transform: scale(1.1);
103+
width: 100%;
104+
height: 100%;
105+
}
106+
.vuemastery-banner-wrapper:after {
107+
content: '';
108+
background: url(/vuemastery/lock-vuemastery.svg) right center no-repeat;
109+
background-size: auto 100%;
110+
position: absolute;
111+
width: 100%;
112+
height: 100%;
113+
top: 0;
114+
left: 0;
115+
pointer-events: none;
116+
}
117+
118+
.vuemastery-banner-wrapper:hover:after {
119+
background-image: url(/vuemastery/unlock-vuemastery.svg);
120+
}
121+
122+
#vm-free-weekend {
123+
position: relative;
124+
width: 100%;
125+
height: 100%;
126+
text-decoration: none;
127+
color: white;
128+
display: flex;
129+
justify-content: center;
130+
align-items: center;
131+
overflow: hidden;
132+
}
133+
134+
#vm-logo-full {
135+
position: absolute;
136+
left: 15px;
137+
width: 120px;
138+
}
139+
140+
#vm-logo-small {
141+
display: none;
142+
}
143+
144+
.vm-free-weekend-wrapper {
145+
display: flex;
146+
align-items: center;
147+
}
148+
149+
.vm-free-weekend-content {
150+
display: flex;
151+
}
152+
153+
.vm-free-weekend-title {
154+
margin: 0;
155+
padding: 0;
156+
font-weight: bold;
157+
font-size: 24px;
158+
text-align: center;
159+
background: linear-gradient(145deg, #c3ffac, #86ec87, #38a56a);
160+
background-clip: text;
161+
-webkit-background-clip: text;
162+
-webkit-text-fill-color: transparent;
163+
}
164+
165+
.vm-free-weekend-sub {
166+
margin: 0 2em;
167+
padding: 0;
168+
font-size: 16px;
169+
text-align: center;
170+
color: #fff;
171+
}
172+
173+
#vm-banner-cta {
174+
position: relative;
175+
margin-left: 10px;
176+
padding: 10px 24px;
177+
background: linear-gradient(to top right, #41b782, #86d169);
178+
border: none;
179+
border-radius: 30px;
180+
color: #fff;
181+
font-size: 12px;
182+
font-weight: bold;
183+
text-decoration: none;
184+
text-transform: uppercase;
185+
}
186+
187+
#vm-banner-cta:hover {
188+
background: linear-gradient(to bottom right, #41b782, #86d169);
189+
}
190+
191+
#vm-banner-close {
192+
position: absolute;
193+
right: 12px;
194+
color: #fff;
195+
font-size: 20px;
196+
font-weight: bold;
197+
display: flex;
198+
align-items: center;
199+
justify-content: center;
200+
}
201+
202+
#vm-banner-close > .close {
203+
width: 20px;
204+
height: 20px;
205+
fill: #fff;
206+
transform: rotate(45deg);
207+
}
208+
209+
@media (max-width: 1200px) {
210+
#vm-banner-cta {
211+
display: none;
212+
}
213+
214+
.vm-free-weekend-content {
215+
flex-direction: column;
216+
}
217+
218+
.vm-free-weekend-sub {
219+
margin: 0 1em;
220+
}
221+
}
222+
223+
@media (max-width: 850px) {
224+
.vuemastery-banner-wrapper:after {
225+
background: none;
226+
}
227+
}
228+
@media (max-width: 767px) {
229+
#vm-logo-full {
230+
left: 10px;
231+
width: 100px;
232+
}
233+
}
234+
@media (max-width: 767px) {
235+
#vm-logo-full {
236+
display: none;
237+
}
238+
#vm-logo-small {
239+
position: absolute;
240+
display: block;
241+
left: 10px;
242+
width: 40px;
243+
}
244+
.vm-free-weekend-title {
245+
font-size: 14px;
246+
}
247+
.vm-free-weekend-sub {
248+
font-size: 12px;
249+
margin: 0;
250+
}
251+
}
252+
253+
.vuemastery-background-dim {
254+
position: absolute;
255+
width: 100%;
256+
height: 100%;
257+
top: 0;
258+
left: 0;
259+
}
260+
.vuemastery-background-dim:after {
261+
content: '';
262+
position: absolute;
263+
top: 0;
264+
left: -100%;
265+
width: 100%;
266+
height: 100%;
267+
background: linear-gradient(
268+
90deg,
269+
transparent,
270+
rgba(255, 255, 255, 0.4),
271+
transparent
272+
);
273+
transition: 0.5s;
274+
transition-delay: 0.5s;
275+
}
276+
.vuemastery-background-dim.show-flash:after {
277+
left: 100%;
278+
}
279+
</style>
280+
281+
<style>
282+
html.vuemastery-menu-fixed .VPNav {
283+
top: 70px;
284+
}
285+
286+
html.vuemastery-menu-fixed {
287+
scroll-padding-top: 134px;
288+
overflow: auto;
289+
}
290+
291+
html.vuemastery-menu-fixed {
292+
margin-top: 72px;
293+
}
294+
295+
@media (max-width: 960px) {
296+
html.vuemastery-menu-fixed .VPNav {
297+
top: 0;
298+
}
299+
}
300+
</style>

.vitepress/theme/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ import {
99
} from './components/preferences'
1010
import SponsorsAside from './components/SponsorsAside.vue'
1111
import VueSchoolLink from './components/VueSchoolLink.vue'
12+
import VueMasteryBanner from './components/VueMasteryBanner.vue'
1213
// import Banner from './components/Banner.vue'
1314
// import TextAd from './components/TextAd.vue'
1415

1516
export default Object.assign({}, VPTheme, {
1617
Layout: () => {
1718
// @ts-ignore
1819
return h(VPTheme.Layout, null, {
19-
// banner: () => h(Banner),
20+
banner: () => h(VueMasteryBanner),
2021
'sidebar-top': () => h(PreferenceSwitch),
2122
'aside-mid': () => h(SponsorsAside)
2223
})

0 commit comments

Comments
 (0)