init
This commit is contained in:
56
src/layouts/Default.vue
Normal file
56
src/layouts/Default.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div id="app" dark>
|
||||
<HeaderPartial v-if="hideHeader!=true" @setTheme="setTheme" :theme="this.theme"></HeaderPartial>
|
||||
<slot/>
|
||||
<NavbarPartial :disableScroll="disableScroll" @setTheme="setTheme" :theme="this.theme"></NavbarPartial>
|
||||
<FooterPartial></FooterPartial>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<static-query>
|
||||
query {
|
||||
metadata {
|
||||
siteName
|
||||
}
|
||||
}
|
||||
</static-query>
|
||||
|
||||
<script>
|
||||
import HeaderPartial from '~/layouts/partials/HeaderWithNavbar.vue'
|
||||
import NavbarPartial from '~/layouts/partials/Navbar.vue'
|
||||
import FooterPartial from '~/layouts/partials/Footer.vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
hideHeader: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disableScroll: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
theme: 'light'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
setTheme(mode) {
|
||||
this.theme = mode
|
||||
}
|
||||
},
|
||||
components: {
|
||||
HeaderPartial,
|
||||
NavbarPartial,
|
||||
FooterPartial
|
||||
},
|
||||
|
||||
metaInfo: {
|
||||
bodyAttrs: {
|
||||
class: "m-0"
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
47
src/layouts/partials/Footer.vue
Normal file
47
src/layouts/partials/Footer.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<nav class="relative bg-black pt-4 pb-16 text-sm text-gray-500">
|
||||
<div class="container mx-auto flex flex-wrap justify-between h-12 items-center">
|
||||
<div class="w-full md:w-1/2 text-center md:text-left">
|
||||
Copyright {{ currentYear }} by {{ $static.metadata.siteName }}
|
||||
| Design by <a href="https://ghost.org" target="_blank" class="hover:text-white">Ghost</a>
|
||||
</div>
|
||||
<div class="w-full md:w-1/2">
|
||||
<ul class="list-none flex justify-center md:justify-end">
|
||||
|
||||
<li
|
||||
:key="element.name"
|
||||
v-for="(element,index) in $static.metadata.navigation"
|
||||
class="hover:text-white"
|
||||
v-bind:class="{'mr-6' : index != Object.keys($static.metadata.navigation).length - 1}"
|
||||
>
|
||||
<a :href="element.link" v-if="element.external" target="_blank" rel="noopener noreferrer">{{ element.name }}</a>
|
||||
<g-link v-else :to="element.link" >{{element.name}}</g-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<static-query>
|
||||
query {
|
||||
metadata {
|
||||
siteName
|
||||
navigation : footerNavigation {
|
||||
name
|
||||
link
|
||||
external
|
||||
}
|
||||
}
|
||||
}
|
||||
</static-query>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
currentYear() {
|
||||
return new Date().getFullYear();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
92
src/layouts/partials/HeaderWithNavbar.vue
Normal file
92
src/layouts/partials/HeaderWithNavbar.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<header class="bg-black relative z-1000 bg-radial-t-gray-to-black" id="header">
|
||||
<nav class="flex items-center justify-between flex-wrap container mx-auto px-4 sm:px-0 py-4">
|
||||
<div class="block flex-grow flex items-center w-auto height-30px">
|
||||
<div class="text-sm flex-grow uppercase">
|
||||
<ul class="list-none flex justify-left text-gray-300 uppercase">
|
||||
<li
|
||||
:key="element.name"
|
||||
v-for="(element,index) in $static.metadata.navigation"
|
||||
class="hover:text-white"
|
||||
v-bind:class="{'mr-4' : index != Object.keys($static.metadata.navigation).length - 1}"
|
||||
>
|
||||
<a
|
||||
:href="element.link"
|
||||
v-if="element.external"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="animated-link"
|
||||
>{{ element.name }}</a>
|
||||
<g-link v-else :to="element.link" class="animated-link">{{element.name}}</g-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="inline-block text-gray-400">
|
||||
<ul class="list-none flex justify-center md:justify-end">
|
||||
<li class="mr-0 sm:mr-6">
|
||||
<theme-switcher v-on="$listeners" :theme="theme"/>
|
||||
</li>
|
||||
<li
|
||||
:key="element.name"
|
||||
v-for="(element,index) in $static.metadata.social"
|
||||
class="hover:text-white hidden sm:block"
|
||||
v-bind:class="{'mr-6' : index != Object.keys($static.metadata.social).length - 1}"
|
||||
>
|
||||
<span class="text-sm">
|
||||
<a :href="element.link" target="_blank" rel="noopener noreferrer">
|
||||
<font-awesome :icon="['fab', element.icon]" />
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="logo pt-0 pb-16 md:pb-32 md:pt-16 container mx-auto text-center text-white">
|
||||
<h2 class="m-0">
|
||||
<span class="text-4xl">
|
||||
<font-awesome :icon="['fas', 'ghost']" class="mb-1 mr-3"></font-awesome>
|
||||
</span>
|
||||
<span class="text-5xl text-white">{{ $static.metadata.siteName }}</span>
|
||||
</h2>
|
||||
<div class="text-gray-400 font-thin text-xl">{{ $static.metadata.siteDescription }}</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import ThemeSwitcher from '~/components/ThemeSwitcher'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
components : {
|
||||
ThemeSwitcher
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<static-query>
|
||||
query {
|
||||
metadata {
|
||||
siteName
|
||||
siteDescription
|
||||
navigation : headerNavigation {
|
||||
name
|
||||
link
|
||||
external
|
||||
}
|
||||
social {
|
||||
icon
|
||||
link
|
||||
}
|
||||
}
|
||||
}
|
||||
</static-query>
|
||||
126
src/layouts/partials/Navbar.vue
Normal file
126
src/layouts/partials/Navbar.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div class="fixed inset-0 h-16 bg-black">
|
||||
<nav
|
||||
class="flex items-center justify-between flex-wrap container mx-auto px-4 sm:px-0 py-4 transition-all transition-500"
|
||||
v-bind:class="{
|
||||
'opacity-100': !disableScroll && scrollPosition > headerHeight,
|
||||
'opacity-0': !disableScroll && scrollPosition < headerHeight
|
||||
}">
|
||||
<div class="block flex-grow flex items-center w-auto">
|
||||
<div class="flex items-center flex-shrink-0 text-white mr-6">
|
||||
<font-awesome :icon="['fas', 'ghost']" class="mr-3"></font-awesome>
|
||||
<span class="font-semibold text-xl tracking-tight">{{ $static.metadata.siteName }}</span>
|
||||
</div>
|
||||
<div class="text-sm flex-grow uppercase">
|
||||
<ul
|
||||
class="list-none flex justify-left text-gray-300 uppercase transition-all transition-500">
|
||||
<li
|
||||
:key="element.name"
|
||||
v-for="(element,index) in $static.metadata.navigation"
|
||||
class="hover:text-white"
|
||||
v-bind:class="{'mr-4' : index != Object.keys($static.metadata.navigation).length - 1}"
|
||||
>
|
||||
<a
|
||||
:href="element.link"
|
||||
v-if="element.external"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="animated-link"
|
||||
>{{ element.name }}</a>
|
||||
<g-link v-else :to="element.link" class="animated-link">{{element.name}}</g-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="inline-block text-gray-400">
|
||||
<ul class="list-none flex justify-center md:justify-end">
|
||||
<li class="mr-0 sm:mr-6">
|
||||
<theme-switcher v-on="$listeners" :theme="theme"/>
|
||||
</li>
|
||||
<li
|
||||
:key="element.name"
|
||||
v-for="(element,index) in $static.metadata.social"
|
||||
class="hover:text-white hidden sm:block"
|
||||
v-bind:class="{'mr-6' : index != Object.keys($static.metadata.social).length - 1}"
|
||||
>
|
||||
<span class="text-sm">
|
||||
<a :href="element.link" target="_blank" rel="noopener noreferrer">
|
||||
<font-awesome :icon="['fab', element.icon]" />
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* I'm a lazy guy, so i used this script
|
||||
* https://codepen.io/ninaregli/pen/OjeMLP
|
||||
* to calculate the current scroll position
|
||||
*
|
||||
* Will be used to add/remove the additional
|
||||
* css classes to show the sticky navbar
|
||||
*/
|
||||
|
||||
import ThemeSwitcher from '~/components/ThemeSwitcher'
|
||||
|
||||
export default {
|
||||
components : {
|
||||
ThemeSwitcher
|
||||
},
|
||||
props: {
|
||||
disableScroll: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
theme: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
scrollPosition: null,
|
||||
headerHeight: 0
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateScroll() {
|
||||
this.scrollPosition = window.scrollY;
|
||||
},
|
||||
setHeaderHeight(height) {
|
||||
this.headerHeight = height;
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if( !this.disableScroll ) {
|
||||
var height = document.getElementById("header").clientHeight;
|
||||
this.setHeaderHeight(height);
|
||||
window.addEventListener("scroll", this.updateScroll);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<static-query>
|
||||
query {
|
||||
metadata {
|
||||
siteName
|
||||
navigation : headerNavigation {
|
||||
name
|
||||
link
|
||||
external
|
||||
}
|
||||
social {
|
||||
icon
|
||||
link
|
||||
}
|
||||
}
|
||||
}
|
||||
</static-query>
|
||||
Reference in New Issue
Block a user