+
@@ -11,7 +12,7 @@
:lessonsInTutorial="lessonsInTutorial"
:lessonPassed="lessonPassed" />
@@ -153,6 +154,7 @@ import Output from './Output.vue'
import Info from './Info.vue'
import Validator from './Validator.vue'
import TutorialCompletionCallout from './callouts/TutorialCompletion.vue'
+import TutorialRedirectModal from './modals/TutorialRedirectModal.vue'
import TypeIcon from './TypeIcon.vue'
const MAX_EXEC_TIMEOUT = isProduction ? 10000 : 60000
@@ -221,6 +223,7 @@ export default {
Info,
Validator,
TutorialCompletionCallout,
+ TutorialRedirectModal,
TypeIcon
},
props: {
diff --git a/src/components/buttons/Button.vue b/src/components/buttons/Button.vue
index d41c8ff0e..fc314fd55 100644
--- a/src/components/buttons/Button.vue
+++ b/src/components/buttons/Button.vue
@@ -7,6 +7,7 @@
:data-loading="loading"
:type="type"
:disabled="loading || disabled"
+ :data-cy="dataCy"
>
{{text}}
@@ -39,7 +40,8 @@ export default {
blur: {
type: Function,
default: () => {}
- }
+ },
+ dataCy: String
}
}
@@ -48,7 +50,8 @@ export default {
button {
position: relative;
opacity: 0.9;
- min-width: 120px;
+ min-width: 7.5rem;
+ min-height: 2.5rem;
box-shadow: inset 0 0 8px rgb(0 0 0 / 0%);
outline: none;
diff --git a/src/components/buttons/ButtonClose.vue b/src/components/buttons/ButtonClose.vue
index 4e9c44867..1ea5a0269 100644
--- a/src/components/buttons/ButtonClose.vue
+++ b/src/components/buttons/ButtonClose.vue
@@ -30,9 +30,11 @@ export default {
Parent needs to have position != static
*/
button.close {
+ --position: 0.4rem;
+
position: absolute;
- top: 1rem;
- right: 1rem;
+ top: var(--position);
+ right: var(--position);
transform: scale(0.95);
padding: 0.5rem;
@@ -65,8 +67,7 @@ button.close {
@media screen and (max-width: 30rem) {
button.close {
- top: 0.3rem;
- right: 0.3rem;
+ --position: 0.3rem;
opacity: 0.8;
transform: scale(0.8);
diff --git a/src/components/buttons/ButtonLink.vue b/src/components/buttons/ButtonLink.vue
index 13350bce9..9f8e78411 100644
--- a/src/components/buttons/ButtonLink.vue
+++ b/src/components/buttons/ButtonLink.vue
@@ -4,7 +4,8 @@
:to="link ? { name: link } : to"
class="inline-flex justify-center avenir dib v-mid fw7 nowrap lh-copy bn br1 pointer bg-navy white outline-focus pv2 ph3"
:disabled="disabled"
- @click="onClick"
+ @click.native="onClick"
+ :data-cy="dataCy"
>
{{text}}
@@ -14,6 +15,7 @@
target="__blank"
@click="onClick"
class="inline-flex justify-center avenir dib v-mid fw7 nowrap lh-copy bn br1 pointer bg-navy white outline-focus pv2 ph3"
+ :data-cy="dataCy"
>
{{text}}
@@ -38,7 +40,8 @@ export default {
onClick: {
type: Function,
default: () => {}
- }
+ },
+ dataCy: String
}
}
@@ -47,7 +50,8 @@ export default {
a {
position: relative;
opacity: 0.9;
- min-width: 120px;
+ min-width: 7.5rem;
+ min-height: 2.5rem;
box-shadow: inset 0 0 8px rgb(0 0 0 / 0%);
outline: none;
user-select: none;
diff --git a/src/components/modals/BaseModal.vue b/src/components/modals/BaseModal.vue
new file mode 100644
index 000000000..562db5ac8
--- /dev/null
+++ b/src/components/modals/BaseModal.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/modals/TutorialRedirectModal.vue b/src/components/modals/TutorialRedirectModal.vue
new file mode 100644
index 000000000..50334918f
--- /dev/null
+++ b/src/components/modals/TutorialRedirectModal.vue
@@ -0,0 +1,174 @@
+
+
+ {{body._1}}{{tutorial.title}}{{body._2}}{{lesson.title}}{{body._3}}
+
+
+
+
+
+
+
+
+
diff --git a/src/config.js b/src/config.js
index 59b4dc356..875d79118 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,3 +1,19 @@
+export const tutorialRedirectModal = {
+ referrer: {
+ SEARCH_ENGINES: [
+ { id: 'google', url: 'google.com' },
+ { id: 'bing', url: 'bing.com' },
+ { id: 'yahoo', url: 'yahoo.com' },
+ { id: 'baidu', url: 'baidu.com' },
+ { id: 'aol', url: 'aol.com' },
+ { id: 'yandex', url: 'yandex.com' },
+ { id: 'duckduckgo', url: 'duckduckgo.com' },
+ { id: 'ecosia', url: 'ecosia.org' },
+ { id: 'qwant', url: 'qwant.com' }
+ ]
+ }
+}
+
export const MAILCHIMP_API_URL = process.env.VUE_APP_MAILCHIMP_API_URL
export const MAILCHIMP_USER_ID = process.env.VUE_APP_MAILCHIMP_USER_ID
export const MAILCHIMP_LIST_ID = process.env.VUE_APP_MAILCHIMP_LIST_ID
@@ -5,5 +21,6 @@ export const MAILCHIMP_LIST_ID = process.env.VUE_APP_MAILCHIMP_LIST_ID
export default {
MAILCHIMP_API_URL,
MAILCHIMP_USER_ID,
- MAILCHIMP_LIST_ID
+ MAILCHIMP_LIST_ID,
+ tutorialRedirectModal
}
diff --git a/src/main.js b/src/main.js
index a4f4ee14f..fe383220c 100644
--- a/src/main.js
+++ b/src/main.js
@@ -5,19 +5,23 @@ import Vue from 'vue'
import VueRouter from 'vue-router'
import VueMeta from 'vue-meta'
import VueTooltip from 'v-tooltip'
+import PortalVue from 'portal-vue'
import VueHighlightJS from 'vue-highlight.js'
import VueSelect from 'vue-select'
+
import 'vue-select/dist/vue-select.css'
import 'highlight.js/styles/github.css'
import App from './App.vue'
import router from './router'
+import stateInit from './state/init'
Vue
.use(VueRouter)
.use(VueMeta, { keyName: 'head', refreshOnceOnNavigation: true })
.use(VueHighlightJS)
.use(VueTooltip)
+ .use(PortalVue)
Vue.component('v-select', VueSelect)
@@ -36,7 +40,10 @@ const root = new Vue({
this.$router.replace({ path: window.location.hash.replace('#', '') })
}
},
- render: h => h(App)
+ render: h => h(App),
+ data: {
+ state: stateInit()
+ }
})
document.addEventListener('DOMContentLoaded', function () {
diff --git a/src/pages/Home.vue b/src/pages/Home.vue
index ab77b470a..b2be93e27 100644
--- a/src/pages/Home.vue
+++ b/src/pages/Home.vue
@@ -56,6 +56,7 @@
/>
+