update webstack

This commit is contained in:
2021-02-08 17:06:59 +02:00
parent b78623ec1c
commit 098fa4e260
313 changed files with 6370 additions and 915 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@@ -1,201 +1,326 @@
@tailwind base;
blockquote {
@apply border-l;
@apply border-l-4;
@apply border-l-blue-500;
@apply pl-4;
@apply italic;
@apply my-8;
p {
padding: 0 !important;
}
@apply border-l;
@apply border-l-4;
@apply border-l-blue-500;
@apply pl-4;
@apply italic;
@apply my-8;
p {
padding: 0 !important;
}
}
pre {
@apply border-l;
@apply border-l-2;
@apply border-l-gray-500;
@apply pl-4;
@apply mt-4;
@apply text-base;
@apply break-words;
@apply overflow-x-auto;
@apply border-l;
@apply border-l-2;
@apply border-l-gray-500;
@apply pl-4;
@apply mt-4;
@apply text-base;
@apply break-words;
@apply overflow-x-auto;
}
ol {
@apply list-decimal;
@apply ml-5;
@apply list-decimal;
@apply ml-5;
}
ul {
@apply list-disc;
@apply ml-5;
@apply list-disc;
@apply ml-5;
}
:not(pre)>code {
@apply text-red-600;
@apply text-base;
:not(pre) > code {
@apply text-red-600;
@apply text-base;
}
@tailwind components;
@tailwind utilities;
@responsive {
.pxi-0 {
@apply px-0 #{!important};
}
.pyi-0 {
@apply py-0 #{!important};
}
.pi-0 {
@apply p-0 #{!important};
}
.pxi-0 {
@apply px-0 #{!important};
}
.pyi-0 {
@apply py-0 #{!important};
}
.pi-0 {
@apply p-0 #{!important};
}
}
.animated-link:after {
content: "";
width: 0px;
height: 1px;
display: block;
transition: 300ms;
@apply bg-gray-500;
}
.animated-link:hover:after {
width: 100%;
content: "";
width: 0px;
height: 1px;
display: block;
transition: 300ms;
@apply bg-gray-500;
}
// .animated-link:hover:after {
// width: 100%;
// }
.height-30px {
height: 30px;
height: 30px;
}
.brandpanel {
background-color: #1072ba;
}
.no-border {
border-width: 0px !important;
border-width: 0px !important;
}
.flex-post {
@apply border-b;
@apply border-b-gray-300;
@apply flex-col;
@apply border-b;
@apply border-b-gray-300;
@apply flex-col;
@apply w-full;
.post-card-image {
@apply h-56;
@apply w-full;
.post-card-image {
@apply h-56;
@apply w-full;
@apply object-cover;
@apply rounded;
@apply relative;
}
.post-card-title {
@apply leading-none;
@apply text-2xl;
@apply font-medium;
}
.post-card-excerpt {
@apply font-serif;
}
@apply object-cover;
@apply rounded;
@apply relative;
}
.post-card-title {
@apply leading-none;
@apply text-2xl;
@apply font-medium;
}
.post-card-excerpt {
@apply font-serif;
}
}
.author-list-item:nth-child(n + 2) {
@apply -ml-3;
@apply -ml-3;
}
button:focus {
outline: none;
outline: none;
}
.telegram_icon{
font-size: 1.2rem;
}
@media (min-width: 768px) {
.with-large>.flex-post:nth-child(5n),
.with-large>.flex-post:nth-child(5n-1) {
// @apply flex-100;
flex: 1 1 50%;
@apply flex-col;
.post-card-image-link {
@apply relative;
min-height: 400px;
}
.post-card-image {
@apply absolute;
@apply h-full;
@apply w-full;
@apply object-cover;
@apply rounded-lg;
}
.post-card-content {
// @apply flex-post-large-content;
flex: 0 1 auto;
@apply self-center;
}
.post-card-title {
@apply text-4xl;
}
.post-card-excerpt {
@apply text-xl;
}
.with-large > .flex-post:nth-child(5n),
.with-large > .flex-post:nth-child(5n-1) {
// @apply flex-100;
flex: 1 1 50%;
@apply flex-col;
.post-card-image-link {
@apply relative;
min-height: 400px;
}
.projects>.flex-post:nth-child(5n),
.projects>.flex-post:nth-child(5n-1) {
.post-card-image-link {
min-height: 300px;
}
.post-card-image {
@apply h-auto;
}
.post-card-image {
@apply absolute;
@apply h-full;
@apply w-full;
@apply object-cover;
@apply rounded-lg;
}
.post-card-content {
// @apply flex-post-large-content;
flex: 0 1 auto;
@apply self-center;
}
.post-card-title {
@apply text-4xl;
}
.post-card-excerpt {
@apply text-xl;
}
}
.news > .flex-post:nth-child(5n),
.news > .flex-post:nth-child(5n-1) {
// @apply flex-100;
flex: 1 1 50%;
@apply flex-col;
.post-card-image-link {
@apply relative;
min-height: 300px;
}
.post-card-image {
@apply absolute;
@apply h-full;
@apply w-full;
@apply object-cover;
@apply rounded-lg;
}
.post-card-content {
// @apply flex-post-large-content;
flex: 0 1 auto;
@apply self-center;
}
.post-card-title {
@apply text-4xl;
}
.post-card-excerpt {
@apply text-xl;
}
}
// .news>.flex-post:nth-child(9n+1),
// .news>.flex-post:nth-child(9n+2) {
// // @apply flex-100;
// flex: 1 1 50%;
// @apply flex-col;
// .post-card-image-link {
// @apply relative;
// min-height: 300px;
// }
// .post-card-image {
// @apply absolute;
// @apply h-full;
// @apply w-full;
// @apply object-cover;
// @apply rounded-lg;
// }
// .post-card-content {
// // @apply flex-post-large-content;
// flex: 0 1 auto;
// @apply self-center;
// }
// .post-card-title {
// @apply text-4xl;
// }
// .post-card-excerpt {
// @apply text-xl;
// }
// }
// .news>.flex-post:nth-child(9n+3),
// .news>.flex-post:nth-child(9n+4),
// .news>.flex-post:nth-child(9n+5) {
// // @apply flex-100;
// flex: 1 1 300px;
// @apply flex-col;
// .post-card-image-link {
// @apply relative;
// min-height: 180px;
// }
// .post-card-image {
// @apply absolute;
// @apply h-full;
// @apply w-full;
// @apply object-cover;
// @apply rounded-lg;
// }
// .post-card-content {
// // @apply flex-post-large-content;
// flex: 0 1 auto;
// @apply self-center;
// }
// .post-card-title {
// @apply text-4xl;
// }
// .post-card-excerpt {
// @apply text-xl;
// }
// }
// .news>.flex-post:nth-child(9n+6),
// .news>.flex-post:nth-child(9n+7),
// .news>.flex-post:nth-child(9n+8),
// .news>.flex-post:nth-child(9n+9) {
// // @apply flex-100;
// flex: 1 1 250px;
// @apply flex-col;
// .post-card-image-link {
// @apply relative;
// min-height: 300px;
// }
// .post-card-image {
// @apply absolute;
// @apply h-full;
// @apply w-full;
// @apply object-cover;
// @apply rounded-lg;
// }
// .post-card-content {
// // @apply flex-post-large-content;
// flex: 0 1 auto;
// @apply self-center;
// }
// .post-card-title {
// @apply text-4xl;
// }
// .post-card-excerpt {
// @apply text-xl;
// }
// }
}
body[data-theme="dark"] {
background-color: #191b1f;
background-color: #191b1f;
@apply text-gray-300;
.post-content-text {
@apply text-gray-300;
.post-content-text {
@apply text-gray-300;
}
.brandpanel {
background-color: #1072ba !important;
}
.text-gray-700,
.text-gray-900 {
@apply text-white;
}
.lg\:shadow-lg {
box-shadow: 0 20px 25px -5px rgba(255, 255, 255, 0.1),
0 10px 10px -5px rgba(255, 255, 255, 0.04);
}
.learn-button {
background-color: #c4c4c4;
@apply text-gray-900;
&:hover {
@apply bg-gray-300;
}
.lg\:shadow-lg{
box-shadow :0 20px 25px -5px rgba(255, 255, 255, 0.1), 0 10px 10px -5px rgba(255, 255, 255, 0.04)
}
.text-indigo-600 {
@apply text-white;
}
.inset-0,
input[type="text"] {
background-color: #191b1f;
}
.bg-white,
.bg-gray-100,
.bg-gray-200 {
background-color: #191b1f;
}
.post-card-excerpt {
@apply text-gray-500;
}
.pagination li {
@apply bg-gray-700;
@apply text-gray-200;
@apply border-gray-600;
&:hover {
@apply bg-gray-600;
@apply text-gray-900;
}
.learn-button{
background-color: #c4c4c4;
@apply text-gray-900;
&:hover {
@apply bg-gray-300;
}
}
.text-gray-700{
}
.pagination li.border-l-black {
@apply border-l-gray-300;
}
pre {
@apply text-gray-500;
}
.flex-post {
@apply border-b-gray-800;
}
.author-list-item img {
border-color: #191b1f;
}
.author-social {
a {
&:hover {
@apply text-white;
}
}
.inset-0 , input[type="text"]{
background-color: #191b1f;
}
.bg-white{
background-color: #191b1f;
}
.post-card-excerpt {
@apply text-gray-500;
}
.pagination li {
@apply bg-gray-700;
@apply text-gray-200;
@apply border-gray-600;
&:hover {
@apply bg-gray-600;
@apply text-gray-900;
}
}
.pagination li.border-l-black {
@apply border-l-gray-300;
}
pre {
@apply text-gray-500;
}
.flex-post {
@apply border-b-gray-800;
}
.author-list-item img {
border-color: #191b1f;
}
.author-social {
a {
&:hover {
@apply text-white;
}
}
}
}
}
}

4
src/components/README.md Normal file
View File

@@ -0,0 +1,4 @@
Add components that will be imported to Pages and Layouts to this folder.
Learn more about components here: https://gridsome.org/docs/components/
You can delete this file.

View File

@@ -0,0 +1,46 @@
<template>
<div>
<nav class="inline-block w-1/4 border-r-2 border-gray-200">
<a
v-for="(slide, index) in slides"
:key="index"
:href="`#${index}`"
class="mt-1 capitalize group flex items-center px-3 py-2 text-sm leading-5 font-medium hover:text-gray-900 hover:bg-gray-400 focus:outline-none transition ease-in-out duration-150"
:class="{
'border-r-3 border-blue-500 hover:bg-gray-100':
activeIndex === index,
}"
@click="setActive(index)"
>
<span class="truncate"> {{ slide.title }} </span>
</a>
</nav>
<div
class="content inline-block h-full w-3/4 align-top p-5 transition ease-in-out duration-150"
>
<div :id="slides[activeIndex]" class="hidden" style="display: block">
<p>
{{ slides[activeIndex].content }}
</p>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["slides"],
data() {
return {
activeIndex: 0,
};
},
methods: {
setActive(index) {
this.activeIndex = index;
},
},
};
</script>

View File

@@ -0,0 +1,17 @@
<template>
<div class="col-span-2 duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-105 ">
<a :href="url" class=" hover:text-threefold-green">
<div class="h-full p-6 bg-white rounded border-t-4 border-green-500 shadow">
<img :src="imgUrl" :lt="imgAlt" class="w-full md:max-w-xl mx-auto">
<h3 class="text-2xl mb-3 font-semibold">{{ title}}</h3>
<p class="text-gray-900">{{ description}}</p>
</div>
</a>
</div>
</template>
<script>
export default {
props: ["imgUrl", "imgAlt", "title", "description", "url"],
};
</script>

View File

@@ -0,0 +1,16 @@
<template>
<a :href="url" class=" hover:text-threefold-green">
<div class="w-full px-6 mb-8 duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-105">
<div class="h-full md:p-6 bg-white rounded border-t-2 border-b-2 border-green-500 ">
<h3 class="text-2xl mb-3 font-semibold">{{ title }}</h3>
<p class="text-gray-900">{{ description }}</p>
</div>
</div>
</a>
</template>
<script>
export default {
props: ["title", "description", "url"],
};
</script>

View File

@@ -0,0 +1,45 @@
<template>
<section class="md:py-16 px-4 md:mx-24 mx-12 w-full container">
<div class="text-center">
<span class="text-green-600 font-semibold">BLOG</span>
<h2 class="text-3xl text-center mt-2 mb-12 font-semibold font-heading">Check our latest blog posts</h2>
</div>
<div v-for="(blog, index) in blogs" :key="blog.id" class="md:grid md:grid-cols-4 grid-cols-1 md:grid-rows-1 md:gap-8 gap-4">
<div v-if="index == 0" class="col-span-2 duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-105 ">
<a :href="blogs[0].url" class=" hover:text-threefold-green">
<div class="h-full p-6 bg-white rounded border-t-4 border-green-500 shadow">
<img :src="blog.image" :alt="blog.imgAlt" class="w-full md:max-w-xl mx-auto">
<h3 class="text-2xl mb-3 font-semibold">{{ blog.title}}</h3>
<p class="text-gray-900">{{ blog.description }}</p>
</div>
</a>
</div>
<div v-if="index > 1 && index < 4" class="col-span-2">
<a :href="blog.url" class="w-full hover:text-threefold-green">
<div class="w-full px-6 mb-8 duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-105">
<div class="h-full md:p-6 bg-white rounded border-t-2 border-green-500 ">
<h3 class="text-2xl mb-3 font-semibold">{{ blog.title }}</h3>
<p class="text-gray-900">{{ blog.description }}</p>
</div>
</div>
</a>
</div>
</div>
<div class="mx-auto text-center my-8">
<a href="#">
<h3 class="text-xl uppercase text-threefold-green font-semibold hover:underline transition duration-300">Join {{blogs.length}} Blog Subscribers</h3>
</a>
</div>
</section>
</template>
<script>
export default {
props: {
blogs: Array
},
};
</script>

View File

@@ -0,0 +1,11 @@
<template>
<div class="mt-8">
<a :href="card.link" class="bg-gray-900 learn-button hover:bg-gray-700 text-gray-100 px-5 py-3 font-semibold rounded">{{ card.button }}</a>
</div>
</template>
<script>
export default {
props:['card']
}
</script>

View File

@@ -0,0 +1,140 @@
<template>
<div
class="flex flex-post px-0 sm:px-4 pb-8 mb-8"
v-bind:class="{ 'no-border': !border }"
>
<g-link :to="path" class="post-card-image-link">
<g-image
:src="record.image"
:alt="record.title"
class="post-card-image"
></g-image>
</g-link>
<div>
<g-link :to="path">
<h2 class="post-card-title mt-3">{{ record.title || record.name }}</h2>
<p class="post-card-excerpt">{{ record.excerpt }}</p>
<section
class="flex flex-wrap post-tags container mx-auto relative py-1"
>
<g-link
v-for="membership in memberships"
:key="membership.id"
:to="membership.path"
class="text-xs bg-transparent hover:text-blue-700 py-1 px-2 mr-1 border hover:border-blue-500 border-gray-600 text-gray-700 rounded-full mb-2"
>{{ membership.title }}</g-link
>
</section>
</g-link>
<div class="w-full post-card-meta pt-2">
<div class="avatars">
<div class="flex items-center">
<div class="flex justify-between items-center">
<ul class="list-none flex author-list m-0">
<li
v-for="author in record.authors"
:key="author.id"
class="author-list-item"
>
<g-link :to="author.path" v-tooltip="author.name">
<g-image
:src="author.image"
:alt="author.name"
class="w-8 h-8 rounded-full bg-gray-200 border-2 border-white"
/>
</g-link>
</li>
</ul>
</div>
<div class="flex flex-col text-xs leading-none uppercase">
<p>
<g-link :to="path">
<time :datetime="record.datetime">{{
record.humanTime
}}</time>
</g-link>
</p>
<p>
<g-link :to="path">
<time :datetime="record.datetime">{{
record.startDate
}}</time>
</g-link>
{{ record.status }}
</p>
</div>
</div>
<section class="post-tags container mx-auto relative py-3" v-if="displaytags()">
<g-link
v-for="tag in record.tags"
:key="tag.id"
:to="tag.path"
class="text-xs bg-transparent hover:text-blue-700 py-2 px-4 mr-2 border hover:border-blue-500 border-gray-600 text-gray-700 rounded-full"
>{{ tag.title }}</g-link
>
</section>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
record: {},
showtags: false,
pathPrefix: "",
border: {
type: Boolean,
default: true,
},
},
computed: {
path(){
if (this.pathPrefix)
return this.pathPrefix + "/" + this.record.id
return this.record.path
},
memberships(){
var res = []
var memberships = this.record.memberships
if (!memberships){
return []
}
memberships.forEach(function(membership){
if(["foundation", "tech"].includes(membership.title)){
res.push(membership)
}
});
return res
}
},
methods: {
displaytags(){
return this.showtags
}
}
}
</script>
<style scoped>
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");
.post-card-excerpt {
font-family: "Roboto", sans-serif;
line-height: 1.2;
}
.post-card-image {
max-width: 100%;
height: auto;
}
</style>

View File

@@ -0,0 +1,139 @@
<template>
<div v-if="card"
class="flex search-post px-0 sm:px-4 pb-8 mb-8"
v-bind:class="{ 'no-border': !border }"
>
<g-link :to="record.path" class="post-card-image-link">
<g-image
:src="record.image"
:alt="record.title"
class="post-card-image"
></g-image>
</g-link>
<div class="p-5">
<g-link :to="record.path">
<h2 class="post-card-title mt-3">{{ record.title || record.name }}</h2>
<p class="post-card-excerpt">{{ record.excerpt }}</p>
<section class="post-tags container mx-auto relative py-1">
<g-link
v-for="membership in record.memberships"
:key="membership.id"
:to="membership.path"
class="text-xs bg-transparent hover:text-blue-700 py-1 px-2 mr-1 border hover:border-blue-500 border-gray-600 text-gray-700 rounded-full"
>{{ membership.title }}</g-link
>
</section>
</g-link>
<div class="w-full post-card-meta pt-2">
<div class="avatars">
<div class="flex items-center">
<div class="flex justify-between items-center">
<ul class="list-none flex author-list m-0">
<li
v-for="author in record.authors"
:key="author.id"
class="author-list-item"
>
<g-link :to="author.path" v-tooltip="author.name">
<g-image
:src="author.image"
:alt="author.name"
class="w-8 h-8 rounded-full bg-gray-200 border-2 border-white"
/>
</g-link>
</li>
</ul>
</div>
<div class="flex flex-col text-xs leading-none uppercase">
<p>
<g-link :to="record.path">
<time :datetime="record.datetime">{{
record.humanTime
}}</time>
</g-link>
</p>
<p>
<g-link :to="record.path">
<time :datetime="record.datetime">{{
record.startDate
}}</time>
</g-link>
{{ record.status }}
</p>
</div>
</div>
<section class="post-tags container mx-auto relative py-3">
<g-link
v-for="tag in record.tags"
:key="tag.id"
:to="tag.path"
class="text-xs bg-transparent hover:text-blue-700 py-2 px-4 mr-2 border hover:border-blue-500 border-gray-600 text-gray-700 rounded-full"
>{{ tag.title }}</g-link
>
</section>
</div>
</div>
</div>
</div>
<div v-else
class="flex search-post px-0 sm:px-4 pb-8 mb-8"
v-bind:class="{ 'no-border': !border }"
>
<div class="p-5">
<g-link :to="record.path">
<h2 class="post-card-title mt-3">{{ record.title}}</h2>
<p class="post-card-excerpt" v-if="record.excerpt" >{{ record.excerpt.substring(100) }}</p>
</g-link>
</div>
</div>
</template>
<script>
export default {
props: {
record: {},
border: {
type: Boolean,
default: true,
},
},
computed: {
card(){return this.record.__typename != "MarkdownPage"},
path(){
if (this.pathPrefix)
return this.pathPrefix + "/" + this.record.id
return this.record.path
}
},
};
</script>
<style scoped>
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");
.post-card-excerpt {
font-family: "Roboto", sans-serif;
line-height: 1.2;
}
.flex-post {
flex-direction: row;
}
.search-post{
border-bottom-width: 1px;
border-bottom-color: #e2e8f0;
width: 100%;
}
.post-card-image {
max-width: 400px;
height: auto;
}
</style>

View File

@@ -0,0 +1,38 @@
<template>
<div class="bg-white">
<div class="max-w-7xl mx-auto py-16 px-4 sm:px-6 lg:py-24 lg:px-8">
<div class="grid grid-cols-1 gap-16">
<div class="lg:grid lg:grid-cols-3 lg:gap-8">
<h2 class="text-4xl mb-6 leading-tight font-semibold font-heading">
Get in touch
</h2>
<div
class="mt-8 grid grid-cols-1 gap-12 sm:grid-cols-2 sm:gap-x-8 sm:gap-y-12 lg:mt-0 lg:col-span-2"
>
<div v-for="(contact, idx) in contacts" :key="idx">
<h4 class="text-lg leading-6 font-medium text-gray-700">
{{ contact.title }}
</h4>
<div class="mt-2 text-base leading-6 text-gray-500">
<div>
{{ contact.mail }}
</div>
</div>
<div class="mt-1">
{{ contact.phone }}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="border-t-2 border-gray-100"></div>
</div>
</template>
<script>
export default {
props: ["contacts"],
};
</script>

View File

@@ -0,0 +1,304 @@
<template>
<div class="fixed inset-0 h-16 bg-white">
<header
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="flex items-center justify-between px-4 py-3 sm:p-0">
<div class="inline-flex items-center flex-shrink-0">
<a href="/" class="flex">
<img
src="/img/TFN_black.svg"
class="mr-3 fill-current"
width="180"
v-if="theme == 'light'"
alt=""
/>
<img
src="/img/TFN_white.svg"
class="mr-3 fill-current"
width="180"
v-else
alt=""
/>
<!-- <span
class="hidden md:block font-semibold text-xl tracking-tight"
>{{ $static.metadata.siteName }}</span
> -->
</a>
</div>
<div class="sm:hidden ml-auto">
<button
@click="isOpen = !isOpen"
type="button"
class="block text-gray-500 focus:outline-none"
>
<svg class="h-6 w-6 fill-current" viewBox="0 0 24 24">
<path
v-if="isOpen"
fill-rule="evenodd"
d="M18.278 16.864a1 1 0 0 1-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 0 1-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 0 1 1.414-1.414l4.829 4.828 4.828-4.828a1 1 0 1 1 1.414 1.414l-4.828 4.829 4.828 4.828z"
/>
<path
v-if="!isOpen"
fill-rule="evenodd"
d="M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"
/>
</svg>
</button>
</div>
<div class="text-gray-400 sm:block md:hidden">
<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 navigation.social"
class="hover:text-white sm:block"
v-bind:class="{
'mr-6': index != Object.keys(navigation.social).length - 1,
}"
>
<span class="telegram_icon">
<a
:href="element.link"
target="_blank"
rel="noopener noreferrer"
>
<font-awesome :icon="['fab', element.icon]" />
</a>
</span>
</li>
</ul>
</div>
</div>
<nav
:class="isOpen ? 'block' : 'hidden'"
class="md:order-2 px-2 pt-2 pb-4 sm:flex sm:p-0 bg-white"
>
<ul
class="list-none sm:flex justify-left uppercase transition-all transition-500"
>
<li
class="py-1"
:key="element.name"
v-for="(element, index) in navigation.navLinks"
:class="{
'mr-2': index != Object.keys(navigation.navLinks).length - 1,
}"
>
<div
v-if="element.expandable"
class="relative"
x-data="{ open: false }"
>
<button
@click="setActive(index)"
class="flex flex-row items-center w-full md:w-auto md:inline md:mt-0 md:ml-4 animated-link"
>
<span class="uppercase">{{ element.name }}</span>
<svg
fill="currentColor"
viewBox="0 0 20 20"
:class="{
'rotate-180': active == index,
'rotate-0': !active == index,
}"
class="inline w-4 h-4 mt-1 ml-1 transition-transform duration-200 transform md:-mt-1"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
</button>
<div
v-if="active == index"
x-show="open"
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute w-full mt-2 origin-top-right rounded-md shadow-lg md:w-48 z-30"
>
<div
v-if="open"
class="px-2 py-2 bg-white rounded-md shadow dark:bg-gray-700"
>
<div v-for="link in element.submenu" :key="link.title">
<a
v-if="link.external"
class="block px-4 py-2 mt-2 text-sm font-semibold bg-transparent rounded-lg dark:bg-transparent dark:hover:bg-gray-600 dark-:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200 md:mt-0 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline"
@click="open = false"
:href="link.path"
target="_blank"
>{{ link.title }}</a
>
<a
v-else
class="block px-4 py-2 mt-2 text-sm font-semibold bg-transparent rounded-lg dark:bg-transparent dark:hover:bg-gray-600 dark-:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200 md:mt-0 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline"
@click="open = false"
:href="link.path"
>{{ link.title }}</a
>
</div>
</div>
</div>
</div>
<g-link
v-else-if="element.external"
:to="element.link"
target="_blank"
class="animated-link"
>{{ element.name }}</g-link
>
<g-link v-else :to="element.link" class="animated-link">{{
element.name
}}</g-link>
</li>
</ul>
<div
class="md:hidden inline-flex rounded-full border-2 border-gray-200 w-1/2"
>
<span class="w-auto flex justify-end items-center p-2">
<font-awesome :icon="['fas', 'search']" />
</span>
<input
class="w-full rounded mr-4 bg-white"
type="text"
placeholder="Search..."
v-model="search"
@keyup.enter="result"
/>
</div>
</nav>
<div class="hidden md:ml-auto md:inline-block md:order-last">
<div class="inline-flex rounded-full border-2 border-gray-200 w-1/2">
<span class="w-auto flex justify-end items-center p-2">
<font-awesome :icon="['fas', 'search']" />
</span>
<input
class="w-full rounded mr-4 bg-white"
type="text"
placeholder="Search..."
v-model="search"
@keyup.enter="result"
/>
</div>
<ul class="list-none inline-flex justify-center md:justify-end">
<li class="mr-0 sm:mr-6">
<ThemeSwitcher v-on="$listeners" :theme="theme" />
</li>
<li
:key="element.name"
v-for="(element, index) in navigation.social"
class="sm:block"
v-bind:class="{
'mr-6': index != Object.keys(navigation.social).length - 1,
}"
>
<span class="telegram_icon">
<a :href="element.link" target="_blank" rel="noopener noreferrer">
<font-awesome :icon="['fab', element.icon]" />
</a>
</span>
</li>
</ul>
</div>
</header>
</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/custom/ThemeSwitcher.vue";
export default {
components: {
ThemeSwitcher,
},
props: {
disableScroll: {
type: Boolean,
default: true,
},
theme: {
type: String,
},
navigation: {
type: Object,
},
},
data: function () {
return {
scrollPosition: null,
headerHeight: 0,
isOpen: false,
search: "",
open: false,
active: null,
};
},
methods: {
updateScroll() {
this.scrollPosition = window.scrollY;
},
setHeaderHeight(height) {
this.headerHeight = height;
},
result() {
window.location.href = `/search?query=${this.search}`;
},
setActive(index) {
this.active = index;
this.open = !this.open;
},
close(e) {
if (!this.$el.contains(e.target)) {
this.open = false;
}
},
},
mounted() {
if (!this.disableScroll) {
var height = document.getElementById("header").clientHeight;
this.setHeaderHeight(height);
window.addEventListener("scroll", this.updateScroll);
}
document.addEventListener("click", this.close);
},
beforeDestroy() {
document.removeEventListener("click", this.close);
},
};
</script>
<style scoped>
input:focus,
button:focus {
outline: 0;
}
.inset-0 {
z-index: 999;
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<div class="my-12">
<nav class="inline-block w-1/4 border-r-2 border-gray-200">
<a
v-for="(slide, index) in slides"
:key="index"
:href="`#${index}`"
class="mt-1 capitalize group flex items-center px-3 py-2 text-sm leading-5 font-medium hover:text-gray-900 focus:outline-none border-blue-500 hover:bg-gray-100 transition ease-in-out duration-150"
:class="{
'border-r-3 border-blue-500 hover:bg-gray-100': activeIndex === index,
}"
@click="setActive(index)"
>
<span> {{ slide.title }} </span>
</a>
</nav>
<div
class="content inline-block h-full w-3/4 align-top p-5 transition ease-in-out duration-150"
>
<div :id="slides[activeIndex]" class="hidden" style="display: block">
<g-image
v-if="slides[activeIndex].image"
:src="
require(`!!assets-loader!@images/sliders/${slides[activeIndex].image}`)
"
:alt="slides[activeIndex].title"
/>
<p>{{ slides[activeIndex].excerpt }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["slides"],
data() {
return {
activeIndex: 0,
};
},
methods: {
setActive(index) {
this.activeIndex = index;
},
},
};
</script>

View File

@@ -0,0 +1,285 @@
<template>
<div class="fixed top-16 left-0 z-50 mb-5 h-16 bg-gray-100 w-full">
<header
class="flex items-center justify-between flex-wrap container mx-auto px-4 py-1 sm:px-0 transition-all transition-500"
>
<div class="flex items-center justify-between px-4 py-2 sm:p-0">
<div class="sm:hidden ml-auto">
<button
@click="isOpen = !isOpen"
type="button"
class="block text-gray-500 focus:outline-none"
>
<svg class="h-6 w-6 fill-current" viewBox="0 0 24 24">
<path
v-if="isOpen"
fill-rule="evenodd"
d="M18.278 16.864a1 1 0 0 1-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 0 1-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 0 1 1.414-1.414l4.829 4.828 4.828-4.828a1 1 0 1 1 1.414 1.414l-4.828 4.829 4.828 4.828z"
/>
<path
v-if="!isOpen"
fill-rule="evenodd"
d="M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"
/>
</svg>
</button>
</div>
<div class="inline-flex items-center flex-shrink-0">
<span class="flex text-xl p-3 capitalize tracking-tight">filter</span>
</div>
</div>
<div class="sm:block md:hidden">
<ul class="list-none inline-flex justify-center md:justify-end">
<li class="py-1 mx-5 cursor-pointer" @click="resetAll()">Reset</li>
</ul>
</div>
<nav
:class="isOpen ? 'flex' : 'hidden'"
class="inline-flex md:order-2 sm:w-28 px-2 pt-2 pb-4 sm:flex sm:p-0 bg-gray-100"
>
<ul
class="list-none sm:flex justify-left capitalize transition-all transition-500"
>
<!-- Topics -->
<li class="py-1 mx-5">
<div class="relative" x-data="{ open: false }">
<button
@click="setActive(0)"
class="flex flex-row items-center w-full md:w-auto md:inline md:mt-0 md:ml-4 animated-link"
>
<span class="capitalize">{{ topic }}</span>
<svg
fill="currentColor"
viewBox="0 0 20 20"
:class="{
'rotate-180': active == 0,
'rotate-0': !active == 0,
}"
class="inline w-4 h-4 mt-1 ml-1 transition-transform duration-200 transform md:-mt-1"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
</button>
<div
v-if="active == 0"
x-show="open"
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute w-full mt-2 origin-top-right rounded-md shadow-lg md:w-48 z-30"
>
<div
v-if="open"
class="w-64 max-h-10 px-2 py-2 bg-white rounded-md shadow dark:bg-gray-700"
>
<a
v-for="topic in topics"
:key="topic"
class="cursor-pointer block px-4 py-2 mt-2 text-sm font-semibold bg-transparent rounded-lg dark:bg-transparent dark:hover:bg-gray-600 dark-:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200 md:mt-0 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline"
@click.self="
setTopic(topic);
open = false;
"
>{{ topic }}</a
>
</div>
</div>
</div>
</li>
<!-- Years -->
<li class="py-1 mx-5">
<div class="relative" x-data="{ open: false }">
<button
@click="setActive(1)"
class="flex flex-row items-center w-full md:w-auto md:inline md:mt-0 md:ml-4 animated-link"
>
<span class="capitalize">{{ year }}</span>
<svg
fill="currentColor"
viewBox="0 0 20 20"
:class="{
'rotate-180': active == 1,
'rotate-0': !active == 1,
}"
class="inline w-4 h-4 mt-1 ml-1 transition-transform duration-200 transform md:-mt-1"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
</button>
<div
v-if="active == 1"
x-show="open"
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute w-full mt-2 origin-top-right rounded-md shadow-lg md:w-48 z-30"
>
<div
v-if="open"
class="w-64 px-2 py-2 bg-white rounded-md shadow dark:bg-gray-700"
>
<a
v-for="year in years"
:key="year"
class="cursor-pointer block px-4 py-2 mt-2 text-sm font-semibold bg-transparent rounded-lg dark:bg-transparent dark:hover:bg-gray-600 dark-:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200 md:mt-0 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline"
@click.self="
setYear(year);
open = false;
"
>{{ year }}</a
>
</div>
</div>
</div>
</li>
<!-- Months -->
<li class="py-1 mx-5">
<div class="relative" x-data="{ open: false }">
<button
@click="setActive(2)"
class="flex flex-row items-center w-full md:w-auto md:inline md:mt-0 md:ml-4 animated-link"
>
<span class="capitalize">{{ month }}</span>
<svg
fill="currentColor"
viewBox="0 0 20 20"
:class="{
'rotate-180': active == 2,
'rotate-0': !active == 2,
}"
class="inline w-4 h-4 mt-1 ml-1 transition-transform duration-200 transform md:-mt-1"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
</button>
<div
v-if="active == 2"
x-show="open"
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute w-full mt-2 origin-top-right rounded-md shadow-lg md:w-48 z-30"
>
<div
v-if="open"
class="w-64 overflow-y-auto h-40 px-2 py-2 bg-white rounded-md shadow dark:bg-gray-700"
>
<a
v-for="month in months"
:key="month"
class="cursor-pointer block px-4 py-2 mt-2 text-sm font-semibold bg-transparent rounded-lg dark:bg-transparent dark:hover:bg-gray-600 dark-:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200 md:mt-0 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline"
@click.self="
setMonth(month);
open = false;
"
>{{ month }}</a
>
</div>
</div>
</div>
</li>
</ul>
</nav>
<div class="hidden md:ml-auto md:inline-block md:order-last">
<ul class="list-none inline-flex justify-center md:justify-end">
<li class="py-1 mx-5 cursor-pointer" @click="resetAll()">Reset</li>
</ul>
</div>
</header>
</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
*/
export default {
props: ["topics", "years", "months"],
data: function () {
return {
isOpen: false,
open: false,
active: null,
listArchive: false,
topic: "All Topics",
year: "All Years",
month: "All Months",
};
},
methods: {
setActive(index) {
this.active = index;
this.open = !this.open;
},
setTopic(event) {
this.$emit("selectedTopic", event);
this.topic = event;
},
setYear(event) {
this.$emit("selectedYear", event);
this.year = event;
},
setMonth(event) {
this.$emit("selectedMonth", event);
this.month = event;
},
resetAll() {
this.$emit("resetAll", true);
this.topic = "All Topics";
this.year = "All Year";
this.month = "All Months";
},
close(e) {
if (!this.$el.contains(e.target)) {
this.open = false;
}
},
},
mounted() {
document.addEventListener("click", this.close);
},
beforeDestroy() {
document.removeEventListener("click", this.close);
},
};
</script>
<style scoped>
.top-16 {
top: 4rem;
}
</style>

View File

@@ -0,0 +1,86 @@
<template>
<ul class="flex pl-0 list-none rounded my-2">
<li class="w-10 relative block text-center py-2 leading-tight bg-white border border-gray-300 text-black ml-0 mr-1 rounded hover:bg-gray-300" v-if="!isFirstPage(currentPage, totalPages)">
<g-link :to="previousPage(currentPage,totalPages)" class="page-link" tabindex="-1" >&laquo;</g-link>
</li>
<li
v-for="page in pages" :key="page.name"
v-bind:class="[isCurrentPage(currentPage, page.name) ? 'border-l-2 border-l-black' : '']"
class="w-10 relative block py-2 text-center leading-tight bg-white border border-gray-300 text-black rounded hover:bg-gray-300 ml-1 mr-1">
<g-link
:to="page.link"
class="page-link"
:aria-label="page.name"
:aria-current="page.name"
>{{page.name}}</g-link>
</li>
<li class="w-10 relative block py-2 text-center leading-tight bg-white border border-gray-300 text-black ml-1 rounded hover:bg-gray-300" v-if="!isLastPage(currentPage, totalPages)">
<g-link :to="nextPage(currentPage,totalPages)" class="page-link" tabindex="-1" >&raquo;</g-link>
</li>
</ul>
</template>
<script>
export default {
props: {
baseUrl: String,
currentPage: Number,
totalPages: Number,
maxVisibleButtons: {
type: Number,
required: false,
default: 3
}
},
methods: {
isFirstPage(currentPage, totalPages) {
return currentPage == 1;
},
isLastPage(currentPage, totalPages) {
return currentPage == totalPages;
},
isCurrentPage(currentPage, pageElement) {
return currentPage == pageElement;
},
nextPage(currentPage, totalPages) {
return `${this.baseUrl}/${currentPage + 1}`;
},
previousPage(currentPage, totalPages) {
return currentPage === 2
? `${this.baseUrl}/`
: `${this.baseUrl}/${currentPage - 1}`;
}
},
computed: {
startPage() {
if (this.currentPage === 1) {
return 1;
}
if (this.currentPage === this.totalPages) {
return this.currentPage - 1;
}
return this.currentPage - 1;
},
pages() {
const range = [];
for (
let i = this.startPage;
i <=
Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages);
i += 1
) {
range.push({
name: i,
isDisabled: i === this.currentPage,
link: i === 1 ? `${this.baseUrl}/` : `${this.baseUrl}/${i}`
});
}
return range;
}
}
};
</script>

View File

@@ -0,0 +1,122 @@
<template>
<div class="fixed top-16 left-0 z-50 mb-5 h-16 bg-gray-100 w-full">
<header
class="flex items-center flex-wrap container mx-auto pt-1 pb-0 sm:px-0 transition-all transition-500"
>
<div class="flex items-center justify-between px-4 sm:p-0">
<div class="inline-flex items-center flex-shrink-0">
<span class="flex text-xl p-3 capitalize tracking-tight"
>filter:</span
>
</div>
</div>
<nav
class="inline-flex md:order-2 px-2 pt-2 pb-4 sm:flex sm:p-0 bg-transparent"
>
<ul
class="list-none sm:flex justify-left capitalize transition-all transition-500"
>
<!-- Tags -->
<li class="pt-2 mx-5">
<div class="relative" x-data="{ open: false }">
<button
@click="setActive(0)"
class="flex flex-row items-center w-full md:w-auto md:inline md:mt-0 md:ml-4 animated-link"
>
<span class="capitalize">{{ selected }}</span>
<svg
fill="currentColor"
viewBox="0 0 20 20"
:class="{
'rotate-180': active == 0,
'rotate-0': !active == 0,
}"
class="inline w-4 h-4 mt-1 ml-1 transition-transform duration-200 transform md:-mt-1"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
</button>
<div
v-if="active == 0"
x-show="open"
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute w-full mt-2 origin-top-right rounded-md shadow-lg md:w-48 z-30"
>
<div
v-if="open"
class="w-64 max-h-10 px-2 py-2 bg-white rounded-md shadow dark:bg-gray-700"
>
<a
v-for="tag in tags"
:key="tag.path"
class="cursor-pointer block px-4 py-2 mt-2 text-sm font-semibold bg-transparent rounded-lg dark:bg-transparent dark:hover:bg-gray-600 dark-:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200 md:mt-0 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline"
:href="tag.path"
@click.self="open = false"
>{{ tag.title }}</a
>
</div>
</div>
</div>
</li>
</ul>
</nav>
</header>
</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
*/
export default {
props: ["tags", "selected"],
data() {
return {
tag: "All",
isOpen: false,
open: false,
active: null,
};
},
methods: {
setActive(index) {
this.active = index;
this.open = !this.open;
},
close(e) {
if (!this.$el.contains(e.target)) {
this.open = false;
}
},
},
mounted() {
document.addEventListener("click", this.close);
},
beforeDestroy() {
document.removeEventListener("click", this.close);
},
};
</script>
<style scoped>
.top-16 {
top: 4rem;
}
</style>

View File

@@ -0,0 +1,44 @@
<template>
<a role="button" @click.prevent="toggleTheme()"
:aria-label="'Toggle ' + nextTheme"
:title="'Toggle ' + nextTheme"
class="toggle-theme"
>
<font-awesome :icon="['fas', 'sun']" class="mr-3" v-if="theme === 'dark'"></font-awesome>
<font-awesome :icon="['fas', 'moon']" class="mr-3" v-if="theme === 'light'"></font-awesome>
</a>
</template>
<script>
let themes = ['light', 'dark']
export default {
props: {
theme: {
type: String,
},
},
computed: {
nextTheme() {
const currentIndex = themes.indexOf(this.theme)
const nextIndex = (currentIndex + 1) % themes.length
return themes[nextIndex]
}
},
methods: {
toggleTheme() {
const currentIndex = themes.indexOf(this.theme);
const nextIndex = (currentIndex + 1) % themes.length;
window.__setPreferredTheme(themes[nextIndex])
this.$emit('setTheme', themes[nextIndex])
}
},
async mounted() {
// set default
if (typeof window.__theme !== 'undefined') this.$emit('setTheme', window.__theme)
}
}
</script>

View File

@@ -0,0 +1,23 @@
<template>
<section class="py-12 px-4 text-center">
<div class="w-full max-w-2xl mx-auto">
<h2 class="text-5xl leading-tight font-semibold font-heading">
{{ cta.title }}
</h2>
<p class="mt-6 mb-8 text-gray-600 leading-relaxed">
{{ cta.excerpt }}
</p>
<g-link
class="bg-gray-900 learn-button hover:bg-gray-700 text-gray-100 px-5 py-3 mr-3 font-semibold rounded shadow"
:to="cta.link"
>{{ cta.button }}</g-link
>
</div>
</section>
</template>
<script>
export default {
props: ["cta"],
};
</script>

View File

@@ -0,0 +1,44 @@
<template>
<section class="py-12 px-4 text-center">
<h2 class="text-4xl mb-2 leading-tight font-semibold font-heading">
{{ main.title }}
</h2>
<p class="text-gray-600">{{ main.description }}</p>
<div class="flex flex-wrap items-center -mx-8 mt-12 mb-2">
<div
class="lg:w-1/3 px-8 mb-8"
v-for="(section, index) in sections"
:key="index"
>
<img
class="w-1/2 mx-auto mb-8 h-32"
:src="section.svg.src"
:alt="section.title"
/>
<h3 class="text-2xl mb-4 font-semibold font-heading">
<span
class="inline-flex items-center justify-center h-12 w-12 mr-2 border rounded-full"
>{{ index + 1 }}</span
>
<span>{{ section.title }}</span>
</h3>
<p class="text-gray-600">
{{ section.excerpt }}
</p>
</div>
</div>
<div>
<g-link
class="bg-gray-900 learn-button hover:bg-gray-700 text-gray-100 px-5 py-3 mr-3 font-semibold rounded shadow"
:to="main.link"
>{{ main.button }}</g-link
>
</div>
</section>
</template>
<script>
export default {
props: ["main", "sections"],
};
</script>

View File

@@ -0,0 +1,38 @@
<template>
<section class="py-12 px-4">
<h2 class="text-3xl text-center mb-12 font-semibold font-heading">
{{ main.title }}
</h2>
<div class="flex flex-wrap -mx-4 mb-6">
<div
v-for="feature in features"
:key="feature.id"
class="lg:w-1/4 px-4 mb-6"
>
<g-image class="w-10 h-10" :src="feature.svg.src"></g-image>
<h3 class="text-xl my-3 font-semibold font-heading">
{{ feature.title }}
</h3>
<p class="text-sm text-gray-600 leading-relaxed">
{{ feature.excerpt }}
</p>
</div>
</div>
<div class="text-center">
<g-link
class="bg-gray-900 learn-button hover:bg-gray-700 text-gray-100 px-5 py-3 mr-3 font-semibold rounded shadow"
:to="main.link"
>{{ main.btn }}</g-link
>
<p class="text-sm text-gray-400 mt-5">
{{ main.excerpt }}
</p>
</div>
</section>
</template>
<script>
export default {
props: ["main", "features"]
};
</script>

View File

@@ -0,0 +1,37 @@
<template>
<section class="py-12 px-4">
<div class="flex flex-wrap items-center text-center lg:text-left -mx-2">
<div class="lg:w-1/2 px-2">
<g-image
class="g-image g-image--lazy g-image--loading"
:src="main.image.src"
:alt="main.title"
></g-image>
</div>
<div class="lg:w-1/2 px-2 lg:pl-16 mt-10 lg:mt-0">
<h2 class="text-4xl px-4 mb-4 leading-tight font-semibold font-heading">
{{ main.title }}
</h2>
<div
class="p-4 mb-4"
:class="{ 'rounded shadow-md': index % 2 !== 0 }"
v-for="(howItWorkSec, index) in HIWData"
:key="index"
>
<h3 class="text-2xl mb-2 font-semibold font-heading">
{{ howItWorkSec.title }}
</h3>
<p class="text-gray-600 leading-relaxed">
{{ howItWorkSec.excerpt }}
</p>
</div>
</div>
</div>
</section>
</template>
<script>
export default {
props: ["HIWData", "main"],
};
</script>

View File

@@ -0,0 +1,62 @@
<template>
<!-- component -->
<div class="container bg-gray-200 mx-auto w-full h-full">
<div class="relative wrap overflow-hidden p-10 h-full">
<div
class="border-2-2 absolute border-opacity-20 border-gray-700 h-full border"
style="left: 50%"
></div>
<div
v-for="(post, index) in roadmap"
:key="index"
class="mb-8 flex justify-between items-center w-full"
:class="{
'flex-row-reverse left-timeline': index % 2 !== 0,
'right-timeline': index % 2 == 0,
}"
>
<div class="order-1 w-5/12"></div>
<div
class="z-20 flex items-center order-1 bg-gray-800 shadow-xl w-8 h-8 rounded-full"
>
<h1 class="mx-auto font-semibold text-lg text-white">
{{ index + 1 }}
</h1>
</div>
<div
class="order-1 rounded-lg shadow-xl w-5/12 px-6 py-4"
:class="{
'bg-red-400': index % 2 !== 0,
'bg-gray-400': index % 2 == 0,
}"
>
<h3
class="mb-3 font-bold text-xl"
:class="{
'text-white': index % 2 !== 0,
'text-gray-800': index % 2 == 0,
}"
>
{{ post.title }}
</h3>
<p
class="text-sm leading-snug tracking-wide text-opacity-100"
:class="{
'text-white': index % 2 !== 0,
'text-gray-800': index % 2 == 0,
}"
>
{{ post.excerpt }}
</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["roadmap"],
};
</script>

View File

@@ -0,0 +1,28 @@
<template>
<section class="py-8 px-4">
<div class="flex flex-wrap items-center -mx-4">
<div class="w-full lg:w-4/6 px-4 mb-8 lg:mb-0 text-center lg:text-left">
<h2 class="text-xl font-semibold font-heading">
{{ signup.title }}
</h2>
</div>
<div class="w-full lg:w-2/6 px-4 text-center">
<g-link
class="bg-gray-900 learn-button hover:bg-gray-700 text-gray-100 px-5 py-3 mr-3 font-semibold rounded shadow"
:to="signup.link1"
>{{ signup.button1 }}</g-link
><g-link
class="text-gray-900 bg-transparent hover:underline"
:to="signup.link2"
>{{ signup.button2 }}</g-link
>
</div>
</div>
</section>
</template>
<script>
export default {
props: ["signup"],
};
</script>

View File

@@ -0,0 +1,32 @@
<template>
<section class="py-12 px-4 text-center">
<div class="w-full max-w-2xl mx-auto">
<span class="text-sm font-semibold">{{ header.title }}</span>
<h2 class="text-5xl mt-2 mb-6 leading-tight font-semibold font-heading">
{{ header.subtitle }}
</h2>
<p class="mb-8 text-gray-600 leading-relaxed">
{{ header.excerpt }}
</p>
<div>
<g-link
class="bg-gray-900 learn-button hover:bg-gray-700 text-gray-100 px-5 py-3 mr-3 font-semibold rounded shadow"
v-if="header.btn1"
:to="header.link1"
>{{ header.btn1 }}</g-link
><g-link
class="text-gray-900 bg-transparent hover:underline"
v-if="header.btn2"
:to="header.link2"
>{{ header.btn2 }}</g-link
>
</div>
</div>
</section>
</template>
<script>
export default {
props: ["header"],
};
</script>

View File

@@ -0,0 +1,52 @@
<template>
<div class="bg-white">
<div class="max-w-screen-xl mx-auto py-16">
<div
class="brandpanel rounded-lg shadow-xl overflow-hidden lg:grid lg:grid-cols-2 lg:gap-4"
>
<div
class="pt-10 pb-12 px-6 sm:pt-16 sm:px-16 lg:py-16 lg:pr-0 xl:py-20 xl:px-20"
>
<div class="lg:self-center">
<h2
class="text-3xl leading-9 font-extrabold text-white sm:text-3xl sm:leading-10"
>
<span class="block">{{ brand.title }}</span>
<span class="block" v-if="brand.subtitle">{{
brand.subtitle
}}</span>
</h2>
<p class="mt-4 text-lg leading-6 text-white">
{{ brand.excerpt }}
</p>
<g-link
:to="brand.sourceUrl"
class="mt-8 bg-white border border-transparent rounded-md shadow px-6 py-3 inline-flex items-center text-base leading-6 font-medium text-gray-900 hover:text-indigo-500 hover:bg-gray-50 transition duration-150 ease-in-out"
>{{ brand.btnTxt }}</g-link
>
</div>
</div>
<div class="relative pb-3/5 -mt-6 md:pb-1/2">
<g-image
class="absolute brandpanel inset-0 w-full h-full transform translate-x-6 translate-y-6 rounded-md object-cover object-left-top sm:translate-x-16 lg:translate-y-20"
:src="image"
:alt="brand.title"
/>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["brand"],
computed: {
image() {
return this.brand.image.src
? this.brand.image.src
: require(`!!assets-loader!@images/brandPanel/${this.brand.image}`);
},
},
};
</script>

View File

@@ -0,0 +1,280 @@
<!--
Tailwind UI components require Tailwind CSS v1.8 and the @tailwindcss/ui plugin.
Read the documentation to get started: https://tailwindui.com/documentation
-->
<template>
<footer class="bg-white">
<div class="max-w-screen-xl mx-auto py-12 px-4 sm:px-6 lg:py-16 lg:px-8">
<div class="xl:grid xl:grid-cols-3 xl:gap-8">
<div class="space-y-8 xl:col-span-1">
<img
class="h-10"
src="/img/tf_icon_black.svg"
alt="Company name"
v-if="theme == 'light'"
/>
<img
class="h-10"
src="/img/tf_icon_white.svg"
alt="Company name"
v-else
/>
<p class="text-gray-500 text-base leading-6">
{{ record.description }}
</p>
<div class="flex space-x-6">
<a
v-if="record.facebook != '#'"
:href="record.facebook"
class="text-gray-400 hover:text-gray-500"
>
<span class="sr-only">Facebook</span>
<svg
class="h-6 w-6"
aria-hidden="true"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
fill-rule="evenodd"
d="M22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V12h2.54V9.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V12h2.773l-.443 2.89h-2.33v6.988C18.343 21.128 22 16.991 22 12z"
clip-rule="evenodd"
/>
</svg>
</a>
<a
v-if="record.instagram != '#'"
:href="record.instagram"
class="text-gray-400 hover:text-gray-500"
>
<span class="sr-only">Instagram</span>
<svg
class="h-6 w-6"
aria-hidden="true"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
fill-rule="evenodd"
d="M12.315 2c2.43 0 2.784.013 3.808.06 1.064.049 1.791.218 2.427.465a4.902 4.902 0 011.772 1.153 4.902 4.902 0 011.153 1.772c.247.636.416 1.363.465 2.427.048 1.067.06 1.407.06 4.123v.08c0 2.643-.012 2.987-.06 4.043-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 01-1.153 1.772 4.902 4.902 0 01-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.048-1.407.06-4.123.06h-.08c-2.643 0-2.987-.012-4.043-.06-1.064-.049-1.791-.218-2.427-.465a4.902 4.902 0 01-1.772-1.153 4.902 4.902 0 01-1.153-1.772c-.247-.636-.416-1.363-.465-2.427-.047-1.024-.06-1.379-.06-3.808v-.63c0-2.43.013-2.784.06-3.808.049-1.064.218-1.791.465-2.427a4.902 4.902 0 011.153-1.772A4.902 4.902 0 015.45 2.525c.636-.247 1.363-.416 2.427-.465C8.901 2.013 9.256 2 11.685 2h.63zm-.081 1.802h-.468c-2.456 0-2.784.011-3.807.058-.975.045-1.504.207-1.857.344-.467.182-.8.398-1.15.748-.35.35-.566.683-.748 1.15-.137.353-.3.882-.344 1.857-.047 1.023-.058 1.351-.058 3.807v.468c0 2.456.011 2.784.058 3.807.045.975.207 1.504.344 1.857.182.466.399.8.748 1.15.35.35.683.566 1.15.748.353.137.882.3 1.857.344 1.054.048 1.37.058 4.041.058h.08c2.597 0 2.917-.01 3.96-.058.976-.045 1.505-.207 1.858-.344.466-.182.8-.398 1.15-.748.35-.35.566-.683.748-1.15.137-.353.3-.882.344-1.857.048-1.055.058-1.37.058-4.041v-.08c0-2.597-.01-2.917-.058-3.96-.045-.976-.207-1.505-.344-1.858a3.097 3.097 0 00-.748-1.15 3.098 3.098 0 00-1.15-.748c-.353-.137-.882-.3-1.857-.344-1.023-.047-1.351-.058-3.807-.058zM12 6.865a5.135 5.135 0 110 10.27 5.135 5.135 0 010-10.27zm0 1.802a3.333 3.333 0 100 6.666 3.333 3.333 0 000-6.666zm5.338-3.205a1.2 1.2 0 110 2.4 1.2 1.2 0 010-2.4z"
clip-rule="evenodd"
/>
</svg>
</a>
<a
v-if="record.twitter != '#'"
:href="record.twitter"
class="text-gray-400 hover:text-gray-500"
>
<span class="sr-only">Twitter</span>
<svg
class="h-6 w-6"
aria-hidden="true"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84"
/>
</svg>
</a>
<a
v-if="record.github != '#'"
:href="record.github"
class="text-gray-400 hover:text-gray-500"
>
<span class="sr-only">GitHub</span>
<svg
class="h-6 w-6"
aria-hidden="true"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
fill-rule="evenodd"
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
clip-rule="evenodd"
/>
</svg>
</a>
<a
v-if="record.dribbble != '#'"
:href="record.dribbble"
class="text-gray-400 hover:text-gray-500"
>
<span class="sr-only">Dribbble</span>
<svg
class="h-6 w-6"
aria-hidden="true"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
fill-rule="evenodd"
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10c5.51 0 10-4.48 10-10S17.51 2 12 2zm6.605 4.61a8.502 8.502 0 011.93 5.314c-.281-.054-3.101-.629-5.943-.271-.065-.141-.12-.293-.184-.445a25.416 25.416 0 00-.564-1.236c3.145-1.28 4.577-3.124 4.761-3.362zM12 3.475c2.17 0 4.154.813 5.662 2.148-.152.216-1.443 1.941-4.48 3.08-1.399-2.57-2.95-4.675-3.189-5A8.687 8.687 0 0112 3.475zm-3.633.803a53.896 53.896 0 013.167 4.935c-3.992 1.063-7.517 1.04-7.896 1.04a8.581 8.581 0 014.729-5.975zM3.453 12.01v-.26c.37.01 4.512.065 8.775-1.215.25.477.477.965.694 1.453-.109.033-.228.065-.336.098-4.404 1.42-6.747 5.303-6.942 5.629a8.522 8.522 0 01-2.19-5.705zM12 20.547a8.482 8.482 0 01-5.239-1.8c.152-.315 1.888-3.656 6.703-5.337.022-.01.033-.01.054-.022a35.318 35.318 0 011.823 6.475 8.4 8.4 0 01-3.341.684zm4.761-1.465c-.086-.52-.542-3.015-1.659-6.084 2.679-.423 5.022.271 5.314.369a8.468 8.468 0 01-3.655 5.715z"
clip-rule="evenodd"
/>
</svg>
</a>
</div>
</div>
<div
class="mt-12 grid md:grid-cols-4 sm:grid-cols-2 xl:mt-0 xl:col-span-2"
>
<!-- class="mt-12 grid grid-cols-2 gap-8 xl:mt-0 xl:col-span-2" -->
<div
v-for="footerLink in record.items"
:key="footerLink.title"
class="md:grid md:grid-cols-3"
>
<div>
<h4
class="text-sm leading-5 font-semibold text-gray-400 tracking-wider uppercase"
>
{{ footerLink.title }}
</h4>
<ul class="mt-4 space-y-4">
<li v-for="item in footerLink.links" :key="item.name">
<a
v-if="item.link.includes('http')"
target="_blank"
:href="item.link"
class="text-base leading-6 text-gray-500 hover:text-gray-900"
>
{{ item.name }}
</a>
<a
v-else
:href="item.link"
class="text-base leading-6 text-gray-500 hover:text-gray-900"
>
{{ item.name }}
</a>
</li>
<!-- <li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Analytics
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Commerce
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Insights
</a>
</li> -->
</ul>
</div>
<!-- <div class="mt-12 md:mt-0">
<h4 class="text-sm leading-5 font-semibold text-gray-400 tracking-wider uppercase">
Support
</h4>
<ul class="mt-4 space-y-4">
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Pricing
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Documentation
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Guides
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
API Status
</a>
</li>
</ul>
</div> -->
</div>
<!-- <div class="md:grid md:grid-cols-2 md:gap-8">
<div>
<h4 class="text-sm leading-5 font-semibold text-gray-400 tracking-wider uppercase">
Company
</h4>
<ul class="mt-4 space-y-4">
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
About
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Blog
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Jobs
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Press
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Partners
</a>
</li>
</ul>
</div>
<div class="mt-12 md:mt-0">
<h4 class="text-sm leading-5 font-semibold text-gray-400 tracking-wider uppercase">
Legal
</h4>
<ul class="mt-4 space-y-4">
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Claim
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Privacy
</a>
</li>
<li>
<a href="#" class="text-base leading-6 text-gray-500 hover:text-gray-900">
Terms
</a>
</li>
</ul>
</div>
</div> -->
</div>
</div>
<div class="mt-12 border-t border-gray-200 pt-8">
<p class="text-base leading-6 text-gray-400 xl:text-center">
&#xA9; 2020 Workflow, Inc. All rights reserved.
</p>
</div>
</div>
</footer>
</template>
<script>
export default {
props: ["record", "theme"],
};
</script>
<style scoped>
ul {
list-style-type: none;
}
</style>

View File

@@ -0,0 +1,34 @@
<template>
<section class="py-12 px-4">
<div class="flex flex-wrap items-center text-center lg:text-left -mx-2">
<div class="lg:w-1/2 px-2 lg:pr-10 mt-10 lg:mt-0 order-1 lg:order-none">
<h2 class="text-4xl mb-6 leading-tight font-semibold font-heading">
{{ title }}
</h2>
<p class="mb-8 text-gray-700 leading-relaxed">{{ excerpt }}</p>
<div v-if="button">
<a
class="inline-block py-4 px-8 mr-6 leading-none text-white bg-gray-900 hover:bg-gray-700 font-semibold rounded shadow"
:href="link"
>{{ button }}</a
>
<!-- <a class="text-gray-600 hover:underline" href="#">Learn more</a> -->
</div>
</div>
<div class="lg:w-1/2 px-2"><img :src="img" :alt="altImg" /></div>
</div>
</section>
</template>
<script>
export default {
props: ["title", "excerpt", "altImg", "image", "button", "link"],
computed: {
img: function () {
if (!this.image) return "";
if (this.image.src) return this.image.src;
return this.image;
},
},
};
</script>

View File

@@ -0,0 +1,34 @@
<template>
<div>
<div class="lg:py-12 lg:flex lg:justify-center flex flex-col">
<div class="bg-white lg:mx-8 lg:flex lg:max-w-5xl lg:shadow-lg lg:rounded-lg">
<div class="lg:w-1/2">
<div class="h-64 bg-cover lg:rounded-lg lg:h-full" :style="img"></div>
</div>
<div class="py-12 px-6 max-w-xl lg:max-w-5xl lg:w-1/2">
<h2 class="text-3xl text-gray-700 font-bold">{{ card.title }}</h2>
<p class="mt-4 text-gray-700">{{ card.excerpt }}</p>
<div class="mt-8" v-if="card.link">
<a :href="card.link" class="bg-gray-900 learn-button hover:bg-gray-700 text-gray-100 px-5 py-3 font-semibold rounded">{{ card.button }}</a>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
computed: {
img: function(){
if(this.card.image.src)
return "background-image:url(" + this.card.image.src + ")"
return this.card.image
}
},
props: ["card"],
};
</script>

View File

@@ -0,0 +1,51 @@
<template>
<div>
<div
class="bannerFondo bg-green-800 bg-left-top bg-auto bg-repeat-x"
style="background-image: url(./img/continuartl_4.png)"
></div>
<div class="-mt-64">
<div class="w-full text-center">
<p class="text-sm tracking-widest text-white">{{ main.subtitle }}</p>
<h1 class="font-bold text-5xl text-white">{{ main.title }}</h1>
</div>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
<div
v-for="(product, idx) in products"
:key="idx"
class="p-2 sm:p-10 text-center cursor-pointer"
>
<div
class="py-16 max-w-sm rounded overflow-hidden shadow-lg hover:bg-white transition duration-500 bg-white"
>
<div class="space-y-10">
<i class="fa fa-spa" style="font-size: 48px"></i>
<div class="px-6 py-4">
<div class="space-y-5">
<div class="font-bold text-xl mb-2">{{ product.title }}</div>
<p class="text-gray-700 text-base">{{ product.excerpt }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["products", "main"],
};
</script>
<style scoped>
.bannerFondo {
height: 400px;
}
</style>

View File

@@ -0,0 +1,27 @@
<template>
<section class="py-0 my-10 px-0 shadow-xl bg-white ">
<div class="flex flex-wrap items-center -mx-8">
<div class="w-1/3 pl-8">
<img class="object-cover" :src="img" :alt="imgAlt"/>
</div>
<div class="w-2/3 px-20 text-left">
<h2 class="text-4xl font-semibold font-tf-secondary">{{ header }}</h2>
<p class="mt-6 mb-8 text-gray-400 leading-relaxed">{{ subtitle }} <br> can benifit everyone on the planet.</p>
<div class="flex ml-52 duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-105">
<a href="#">
<svg class="fill-current text-green-600 h-11 w-11 " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 430.04 315.72"><title>Arrows</title><path class="cls-1" d="M46.17,96.56l84.05,0a18.74,18.74,0,0,1,19.7,9.16L274.84,244.54a14.64,14.64,0,0,1,3.74,11,14.24,14.24,0,0,1-3.74,8.19L149.26,402.36a17.41,17.41,0,0,1-19.78,9.14l-83.7.5c-.48-.14-8.05-2.47-10.24-10.14a15.37,15.37,0,0,1,2.22-12.61L159,254.1,36.28,116.58c-.28-.65-3-7.18.79-13.43A14.9,14.9,0,0,1,46.17,96.56Z" transform="translate(-35 -96.28)"/><path class="cls-1" d="M232.57,96.56l84.05,0a18.74,18.74,0,0,1,19.7,9.16L461.24,244.54a14.69,14.69,0,0,1,3.73,11,14.25,14.25,0,0,1-3.73,8.19L335.65,402.36a17.39,17.39,0,0,1-19.77,9.14l-83.71.5c-.47-.14-8-2.47-10.23-10.14a15.37,15.37,0,0,1,2.22-12.61L345.39,254.1,222.68,116.58c-.28-.65-3-7.18.79-13.43A14.9,14.9,0,0,1,232.57,96.56Z" transform="translate(-35 -96.28)"/></svg>
</a><a class="inline-block text-green-600 hover:underline py-2 ml-6 uppercase text-right font-bold" href="#">{{ link_text }}</a>
</div>
</div>
</div>
</section>
</template>
<script>
export default {
props: ["header", "subtitle","link_text","img","imgAlt"],
};
</script>

View File

@@ -0,0 +1,29 @@
<template>
<section class="pt-8 px-4 text-center">
<div class="max-w-2xl mx-auto mb-8">
<h2 class="text-4xl leading-tight mb-6 font-semibold font-heading">Our Partners</h2>
<p class="text-gray-400 leading-relaxed"></p>
</div>
<div class="flex flex-wrap -mx-8">
<div v-for="(logo ,idx) in logos" :key="idx" class="w-1/2 md:w-1/6 px-8 mb-8">
<img :src="logo.image.src" alt />
</div>
</div>
</section>
</template>
<script>
export default {
props: ["logos"],
computed: {
img: function() {
if (!this.image) return "";
if (this.image.src) return this.image.src;
return this.image;
}
}
};
</script>

View File

@@ -0,0 +1,34 @@
<template>
<section class="py-12 px-4 text-center">
<h2 class="text-4xl mb-2 leading-tight font-semibold font-heading">THREEFOLD TEAM</h2>
<p class="max-w-xl mx-auto mb-12 text-gray-400">The heartbeat behind the ThreeFold Movement.</p>
<div class="flex max-w-lg mb-12 mx-auto text-center border-b-2">
<div v-for="(filter, index) in filters" :key="filter" class="w-1/3 pb-2">
<button v-if="index == 0" class="w-1/3 pb-2 border-b-4 border-indigo-600">{{ filter }}</button>
<button v-if="index != 0" class="hover:text-indigo-600">{{ filter }}</button>
</div>
</div>
<div class="flex flex-wrap -mx-4">
<div v-for="person in people" :key="person.id" class="w-1/2 lg:w-1/4 p-4">
<img class="w-1/2 mx-auto mb-4 rounded-full" :src="person.img" :alt="person.imgAlt">
<h3 class="text-xl mb-1 font-semibold font-heading font-semibold">{{ person.name }}</h3>
<span>{{ person.title }}</span>
</div>
</div>
</section>
</template>
<script>
export default {
props: {
people: Array,
filters: Array
}
}
</script>

View File

@@ -0,0 +1,27 @@
<template>
<div class="py-12 bg-white">
<div class="max-w-xl mx-auto px-4 sm:px-6 lg:max-w-screen-xl lg:px-8">
<h2 class="text-gray-500">Next Events</h2>
<div class="lg:grid lg:grid-cols-2 lg:gap-8">
<a href="#">
<div class="mt-5 px-10 mt-10 py-4 border-l-2 border-gray-200">
<a href="#"><h3 class="leading-6 font-medium text-gray-700 hover:text-blue-500">{{ title1 }}</h3></a>
<p class="mt-2 text-lg leading-6 text-gray-400">
{{ subtitle1 }}
</p>
<p class="leading-6 font-medium text-gray-600">{{ date }}</p>
</div>
</a>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["title1", "subtitle1","date"],
};
</script>

View File

@@ -0,0 +1,36 @@
<template>
<div class="bg-white">
<div class="max-w-screen-xl mx-auto py-12 px-4 sm:px-6 lg:py-16 lg:px-8">
<p
class="text-center text-base leading-6 font-semibold uppercase text-gray-600 tracking-wider"
>
{{ news.excerpt }}
</p>
<div class="mt-6 grid grid-cols-2 gap-0.5 md:grid-cols-3 lg:mt-8">
<g-link
v-for="partner in news.partners"
:key="partner.id"
:to="partner.path"
target="_blank"
class="col-span-1 flex justify-center py-8 px-8 m-1 bg-gray-100"
>
<!-- <img
class="max-h-12"
:src="require(`!!assets-loader!@images/${partner.logo}`)"
/> -->
<img
class="max-h-12"
:src="partner.logo"
/>
</g-link>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["news"],
};
</script>

View File

@@ -0,0 +1,103 @@
<template>
<div class="bg-white">
<div class="max-w-screen-xl mx-auto py-24 px-4 sm:px-6 lg:px-8">
<div class="sm:flex sm:flex-col sm:align-center">
<h1
class="text-5xl leading-none font-extrabold text-gray-900 sm:text-center"
>
{{ main.title }}
</h1>
<p class="mt-5 text-xl leading-7 text-gray-500 sm:text-center">
{{ main.excerpt }}
</p>
<div
class="relative self-center mt-6 bg-gray-100 rounded-lg p-0.5 flex sm:mt-8"
>
<button
type="button"
class="relative w-1/2 bg-white border-gray-200 rounded-md shadow-sm py-2 text-sm leading-5 font-medium text-gray-700 whitespace-no-wrap hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue focus:z-10 active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150 sm:w-auto sm:px-8"
>
{{ main.button1 }}
</button>
<button
type="button"
class="relative w-1/2 border border-transparent rounded-md py-2 text-sm leading-5 font-medium text-gray-700 whitespace-no-wrap hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue focus:z-10 active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150 sm:w-auto sm:px-8"
>
{{ main.button2 }}
</button>
</div>
</div>
<div
class="mt-12 space-y-4 sm:mt-16 sm:space-y-0 sm:grid sm:grid-cols-2 sm:gap-6 lg:max-w-4xl lg:mx-auto xl:max-w-none xl:mx-0 xl:grid-cols-4"
>
<div
v-for="(plan, index) in pricingPlans"
:key="index"
class="border border-gray-200 rounded-lg shadow-sm divide-y divide-gray-200"
>
<div class="p-6">
<h2 class="text-lg leading-6 font-medium text-gray-900">
{{ plan.title }}
</h2>
<p class="mt-4 text-sm leading-5 text-gray-500">
{{ plan.excerpt }}
</p>
<p class="mt-8">
<span class="text-4xl leading-10 font-extrabold text-gray-900">{{
plan.price
}}</span>
<span class="text-base leading-6 font-medium text-gray-500"
>/{{ plan.duration }}</span
>
</p>
<g-link
type="button"
:to="plan.link"
class="mt-8 w-full text-center bg-gray-800 border border-gray-800 rounded-md py-2 text-sm leading-5 font-semibold text-white hover:bg-gray-700 focus:outline-none focus:shadow-outline-gray transition duration-150 ease-in-out"
>
{{ plan.button }}
</g-link>
</div>
<div class="pt-6 pb-8 px-6">
<h3
class="text-xs leading-4 font-medium text-gray-900 tracking-wide uppercase"
>
{{ plan.includeTitle }}
</h3>
<ul class="mt-6 space-y-4">
<li
class="flex space-x-3"
v-for="option in plan.options"
:key="option.id"
>
<!-- Heroicon name: check -->
<svg
class="flex-shrink-0 h-5 w-5 text-green-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
<span class="text-sm leading-5 text-gray-500">{{
option
}}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["main", "pricingPlans"],
};
</script>

View File

@@ -0,0 +1,343 @@
<template>
<div class="bg-white">
<div
class="max-w-screen-xl mx-auto bg-white py-16 sm:py-24 sm:px-6 lg:px-8"
>
<!-- xs to lg -->
<div class="max-w-2xl mx-auto lg:hidden">
<table class="mt-8 w-full" v-for="plan in plans" :key="plan.id">
<caption
class="bg-gray-100 border-t border-gray-200 py-3 px-4 text-sm leading-5 font-medium text-gray-900 text-left"
>
{{
plan.title
}}
</caption>
<tbody
class="divide-y divide-gray-200"
v-for="plan in plan.rows"
:key="plan.id"
>
<tr class="border-t border-gray-200">
<th
class="py-5 px-4 text-sm leading-5 font-normal text-gray-500 text-left"
scope="row"
>
{{ plan.title }}
</th>
<td class="py-5 pr-4" v-if="plan.firstCol == 'include'">
<!-- Heroicon name: check -->
<svg
class="ml-auto h-5 w-5 text-green-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">Yes</span>
</td>
<td class="py-5 pr-4" v-else-if="plan.firstCol == 'none'">
<!-- Heroicon name: minus -->
<svg
class="ml-auto h-5 w-5 text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">No</span>
</td>
<td class="py-5 pr-4" v-else>
<span
class="block text-sm leading-5 text-gray-700 text-right"
>{{ plan.firstCol }}</span
>
</td>
<td class="py-5 pr-4" v-if="plan.secCol == 'include'">
<!-- Heroicon name: check -->
<svg
class="ml-auto h-5 w-5 text-green-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">Yes</span>
</td>
<td class="py-5 pr-4" v-else-if="plan.secCol == 'none'">
<!-- Heroicon name: minus -->
<svg
class="ml-auto h-5 w-5 text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">No</span>
</td>
<td class="py-5 pr-4" v-else>
<span
class="block text-sm leading-5 text-gray-700 text-right"
>{{ plan.secCol }}</span
>
</td>
<td class="py-5 pr-4" v-if="plan.thirdCol == 'include'">
<!-- Heroicon name: check -->
<svg
class="ml-auto h-5 w-5 text-green-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">Yes</span>
</td>
<td class="py-5 pr-4" v-else-if="plan.thirdCol == 'none'">
<!-- Heroicon name: minus -->
<svg
class="ml-auto h-5 w-5 text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">No</span>
</td>
<td class="py-5 pr-4" v-else>
<span
class="block text-sm leading-5 text-gray-700 text-right"
>{{ plan.thirdCol }}</span
>
</td>
</tr>
</tbody>
</table>
</div>
<!-- lg+ -->
<div class="hidden lg:block">
<table class="w-full h-px table-fixed">
<thead>
<tr>
<th
class="pb-4 px-6 text-sm leading-5 font-medium text-gray-900 text-left"
scope="col"
>
<span class="sr-only">Feature by</span>
<span>Plans</span>
</th>
<th
class="w-1/4 pb-4 px-6 text-lg leading-6 font-medium text-gray-900 text-left"
scope="col"
>
Basic
</th>
<th
class="w-1/4 pb-4 px-6 text-lg leading-6 font-medium text-gray-900 text-left"
scope="col"
>
Essential
</th>
<th
class="w-1/4 pb-4 px-6 text-lg leading-6 font-medium text-gray-900 text-left"
scope="col"
>
Premium
</th>
</tr>
</thead>
<tbody
class="border-t border-gray-200 divide-y divide-gray-200"
v-for="plan in plans"
:key="plan.id"
>
<tr>
<th
class="bg-gray-100 py-3 pl-6 text-sm leading-5 font-medium text-gray-900 text-left"
colspan="4"
scope="colgroup"
>
{{ plan.title }}
</th>
</tr>
<tr v-for="plan in plan.rows" :key="plan.id">
<th
class="py-5 px-6 text-sm leading-5 font-normal text-gray-500 text-left"
scope="row"
>
{{ plan.title }}
</th>
<td class="py-5 px-6" v-if="plan.firstCol == 'include'">
<!-- Heroicon name: check -->
<svg
class="h-5 w-5 text-green-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
</td>
<td class="py-5 px-6" v-else-if="plan.firstCol == 'none'">
<!-- Heroicon name: minus -->
<svg
class="h-5 w-5 text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
</svg>
</td>
<td class="py-5 px-6" v-else>
<span class="block text-sm leading-5 text-gray-700">{{
plan.firstCol
}}</span>
</td>
<td class="py-5 px-6" v-if="plan.secCol == 'include'">
<!-- Heroicon name: check -->
<svg
class="h-5 w-5 text-green-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">Included in Essential</span>
</td>
<td class="py-5 px-6" v-else-if="plan.secCol == 'none'">
<!-- Heroicon name: minus -->
<svg
class="h-5 w-5 text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
</svg>
</td>
<td class="py-5 px-6" v-else>
<span class="block text-sm leading-5 text-gray-700">{{
plan.secCol
}}</span>
</td>
<td class="py-5 px-6" v-if="plan.thirdCol == 'include'">
<!-- Heroicon name: check -->
<svg
class="h-5 w-5 text-green-500"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
<span class="sr-only">Included in Premium</span>
</td>
<td class="py-5 px-6" v-else-if="plan.thirdCol == 'none'">
<svg
class="h-5 w-5 text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
</svg>
</td>
<td class="py-5 px-6" v-else>
<span class="block text-sm leading-5 text-gray-700">{{
plan.thirdCol
}}</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["plans"],
};
</script>

View File

@@ -0,0 +1,24 @@
<template>
<div>
<img class="rounded" :src="img" :alt="imgAlt" />
<div class="mt-2">
<div>
<div class="text-xs text-gray-600 uppercase font-bold">
{{ eyebrow }}
</div>
<div class="font-bold text-gray-700 leading-snug">
<a :href="url" class="hover:underline">{{ title }}</a>
</div>
<div class="mt-2 text-sm text-gray-600">{{ pricing }}</div>
</div>
</div>
</div>
<!-- TODO: how do I get markdown in here? -->
</template>
<script>
export default {
props: ["img", "imgAlt", "eyebrow", "title", "pricing", "url"],
};
</script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 327 B

View File

@@ -1,45 +1,28 @@
<template>
<div id="app" dark class="flex flex-col font-sans">
<HeaderPartial
v-if="hideHeader != true"
<div class="container mx-auto">
<NavBar
:navigation="$static.navigation"
@setTheme="setTheme"
:theme="this.theme"
></HeaderPartial>
<NavbarPartial
:disableScroll="disableScroll"
@setTheme="setTheme"
:theme="this.theme"
></NavbarPartial>
/>
<slot />
<FooterPartial></FooterPartial>
<Footer
:record="$static.footer"
@setTheme="setTheme"
:theme="this.theme" />
</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";
import NavBar from "~/components/custom/Navbar/Navbar.vue";
import Footer from "~/components/marketing/sections/cta-sections/Footer.vue";
export default {
props: {
hideHeader: {
type: Boolean,
default: true,
},
disableScroll: {
type: Boolean,
default: true,
},
components: {
NavBar,
Footer,
},
data: function () {
data() {
return {
theme: "light",
};
@@ -49,16 +32,75 @@ export default {
this.theme = mode;
},
},
components: {
HeaderPartial,
NavbarPartial,
FooterPartial,
},
metaInfo: {
bodyAttrs: {
class: "m-0 pt-12",
},
},
};
</script>
</script>
<static-query>
query {
metadata {
siteName
}
navigation(id: "navigation"){
navLinks{
name
link
external
expandable
submenu {
title
path
external
}
}
social{
icon
link
}
}
footer(id: "footer"){
facebook
github
twitter
dribbble
instagram
description
items{
title
links{
name
link
}
}
}
}
</static-query>
<style>
body {
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
margin: 0;
padding-top: 100px;
line-height: 1.5;
}
.layout {
max-width: 760px;
margin: 0 auto;
padding-left: 20px;
padding-right: 20px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
height: 80px;
}
.nav__link {
margin-left: 20px;
}
</style>

5
src/layouts/README.md Normal file
View File

@@ -0,0 +1,5 @@
Layout components are used to wrap pages and templates. Layouts should contain components like headers, footers or sidebars that will be used across the site.
Learn more about Layouts: https://gridsome.org/docs/layouts/
You can delete this file.

View File

@@ -1,4 +1,6 @@
import DefaultLayout from '~/layouts/Default.vue'
// This is the main.js file. Import global CSS and scripts here.
// The Client API can be used here. Learn more: gridsome.org/docs/client-api
import DefaultLayout from '~/layouts/Default.vue';
import VTooltip from 'v-tooltip'
import '~/assets/scss/main.scss';
@@ -9,23 +11,19 @@ import { fas } from '@fortawesome/free-solid-svg-icons';
import { fab } from '@fortawesome/free-brands-svg-icons'
import '@fortawesome/fontawesome-svg-core/styles.css';
import VacationCard from "~/components/VacationCard.vue";
require("gridsome-plugin-remark-prismjs-all/themes/night-owl.css");
require("prismjs/themes/prism-solarizedlight.css");
config.autoAddCss = false;
library.add(fas);
library.add(fab);
export default function (Vue, {router, head, isClient}) {
Vue.component('Layout', DefaultLayout)
Vue.component('VacationCard', VacationCard)
Vue.component('font-awesome', FontAwesomeIcon)
Vue.use(VTooltip, {
defaultPlacement: 'top-end',
defaultClass: 'bg-black text-xs px-2 leading-normal py-1 rounded absolute text-gray-400 max-w-xs mb-1'
})
var VueMarkdown = require('vue-markdown');
Vue.use(VueMarkdown);
export default function(Vue, { router, head, isClient }) {
// Set default layout as a global component
Vue.component('Layout', DefaultLayout)
Vue.component('font-awesome', FontAwesomeIcon)
Vue.use(VTooltip, {
defaultPlacement: 'top-end',
defaultClass: 'bg-black text-xs px-2 leading-normal py-1 rounded absolute text-gray-400 max-w-xs mb-1'
})
}

View File

@@ -1,58 +0,0 @@
<template>
<Layout :hiddenHeader="true" :disableScroll="true">
<div
class="container sm:pxi-0 mx-auto overflow-x-hidden"
:style="{ 'min-height': contentHeight + 'px' }"
>
<VerticalNav :slides="getNode" />
</div>
</Layout>
</template>
<script>
import VerticalNav from "~/components/VerticalNav.vue";
export default {
metaInfo: {
title: "About us",
},
computed: {
contentHeight() {
if (process.isClient) {
return window.innerHeight - 130;
}
},
getNode() {
let result = [];
for (const edge of this.$page.entries.edges) {
result.push(edge.node);
}
return result;
},
},
components: {
VerticalNav,
},
};
</script>
<page-query>
query {
entries: allSlides ( sortBy: "rank"){
edges {
node {
rank
id
title
img
content
}
}
}
}
</page-query>
<style scoped>
.hand {
width: 70%;
}
</style>

View File

@@ -1,33 +1,42 @@
<template>
<Layout>
<div
class="container sm:pxi-0 mx-auto"
<NewsFilterHeader
@selectedTopic="setTopic"
@selectedYear="setYear"
@selectedMonth="setMonth"
@resetAll="resetAll"
:topics="topics"
:years="years"
:months="months"
/>
<div
class="container sm:pxi-0 mx-auto mt-8"
:style="{ 'min-height': contentHeight + 'px' }"
>
<div class="flex flex-wrap with-large pt-8 pb-8 mx-4 sm:-mx-4">
<div class="flex flex-wrap news pt-12 mt-8 pb-8 mx-4 sm:-mx-4">
<PostListItem
v-for="edge in $page.entries.edges"
:key="edge.node.id"
:record="edge.node"
v-for="post in blogs.edges"
:key="post.node.id"
:record="post.node"
/>
</div>
</div>
<div class="pagination flex justify-center mb-8">
<div class="pagination flex justify-center mb-8">
<Pagination
:baseUrl="baseurl"
:currentPage="$page.entries.pageInfo.currentPage"
:totalPages="$page.entries.pageInfo.totalPages"
baseUrl=""
:currentPage="blogs.pageInfo.currentPage"
:totalPages="blogs.pageInfo.totalPages"
:maxVisibleButtons="5"
v-if="$page.entries.pageInfo.totalPages > 1"
v-if="blogs.pageInfo.totalPages > 1"
/>
</div>
</div>
</Layout>
</template>
<page-query>
query{
entries: allBlog(sortBy: "created", order: DESC) {
totalCount
pageInfo {
@@ -37,12 +46,17 @@ query{
edges {
node {
title
tags{
id
title
path
}
excerpt
image(width:800)
path
humanTime : created(format:"DD MMM YYYY")
datetime : created
author {
authors {
id
name
image(width:64, height:64, fit:inside)
@@ -51,31 +65,172 @@ query{
}
}
}
topics: allBlogTag{
edges{
node{
title
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/PostListItem.vue";
import Pagination from "~/components/Pagination.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import Pagination from "~/components/custom/Pagination.vue";
import NewsFilterHeader from "~/components/custom/NewsFilterHeader.vue";
export default {
data() {
const allMonths = [
"All",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
const currYear = new Date().getFullYear();
var years = ["All"]
var r = this.range(2019, currYear)
r.forEach((year) => years.push(String(year)));
return {
selectedTopic: "All",
selectedYear: "All",
selectedMonth: "All",
months: allMonths,
years: years,
listArchive: false,
archiveButtonText : "Archive"
};
},
metaInfo: {
title: "Home",
title: "Newsroom",
},
components: {
PostListItem,
Pagination,
NewsFilterHeader,
},
methods: {
setTopic: function (topic) {
this.selectedTopic = topic;
},
setYear(year) {
this.selectedYear = year;
},
setMonth(month) {
this.selectedMonth = month;
},
resetAll() {
this.selectedTopic = "All";
this.selectedYear = "All";
this.selectedMonth = "All";
},
range(start, end, step) {
var range = [];
var typeofStart = typeof start;
var typeofEnd = typeof end;
if (step === 0) {
throw TypeError("Step cannot be zero.");
}
if (typeofStart == "undefined" || typeofEnd == "undefined") {
throw TypeError("Must pass start and end arguments.");
} else if (typeofStart != typeofEnd) {
throw TypeError("Start and end arguments must be of same type.");
}
typeof step == "undefined" && (step = 1);
if (end < start) {
step = -step;
}
if (typeofStart == "number") {
while (step > 0 ? end >= start : end <= start) {
range.push(start);
start += step;
}
} else if (typeofStart == "string") {
if (start.length != 1 || end.length != 1) {
throw TypeError("Only strings with one character are supported.");
}
start = start.charCodeAt(0);
end = end.charCodeAt(0);
while (step > 0 ? end >= start : end <= start) {
range.push(String.fromCharCode(start));
start += step;
}
} else {
throw TypeError("Only string and number types are supported");
}
return range;
}
},
computed: {
baseurl: function () {
return "";
},
topics: function () {
var res = ["All"];
this.$page.topics.edges.forEach((edge) => res.push(edge.node.title));
return res;
},
contentHeight() {
if (process.isClient) {
return window.innerHeight - 100;
}
},
},
blogs() {
var res = {};
var old = this.$page.entries;
res.totalCount = old.totalCount;
res.pageInfo = old.pageInfo;
res.edges = [];
for (var i = 0; i < old.edges.length; i++) {
var node = old.edges[i].node;
// Now check topic
var topics = ["All"];
node.tags.forEach((tag) => topics.push(tag.title));
var nodeDate = new Date(node.datetime);
if (!topics.includes(this.selectedTopic)) continue;
// Check year
var years = ["All", String(nodeDate.getFullYear())];
if (!years.includes(this.selectedYear)) continue;
// Check Month
var months = ["All", this.months[nodeDate.getMonth() + 1]];
if (!months.includes(this.selectedMonth)) continue;
res.edges.push({ node: node, id: node.id });
}
return res;
},
},
};
</script>

View File

@@ -1,143 +1,59 @@
<template>
<Layout :hideHeader="true" :disableScroll="true">
<div class="container sm:pxi-0 mx-auto overflow-hidden">
<!-- <VacationCard img="" imgAlt="" eyebrow="" title="" pricing="" url="" /> -->
<Header
v-for="header in headers"
:key="header.title"
:header="header"
<div class="container sm:pxi-0 mx-auto overflow-x-hidden py-5">
<Header
:title="$page.markdownPage.header_title"
:image="$page.markdownPage.header_image"
:altImg="$page.markdownPage.header_altImg"
:excerpt="$page.markdownPage.header_excerpt"
:button="$page.markdownPage.button"
:link="$page.markdownPage.link"
/>
<!-- <div class="py-10 flex flex-col">
<section class="py-10">
<div class="flex flex-wrap items-center -mx-8">
<div class="md:ml-auto md:w-1/2 md:pl-20 px-10">
<h2 class="text-4xl font-bold font-tf-secondary">
Welcome to the growing ecosystem of ThreeFold
</h2>
<p class="text-gray-600 leading-relaxed">Welcome to the growing ecosystem of ThreeFold</p>
</div>
<div class="md:ml-auto md:w-1/2 pl-8">
<img class="object-cover" src="img/equality.png" alt="imgAlt" />
</div>
</div>
</section>
</div> -->
<!-- <section class="py-5 m-5 px-0 shadow-xl border border-gray-300">
<div class="flex flex-wrap items-center -mx-8">
<div class="md:ml-auto md:w-1/3 pl-8">
<img
src="img/projects_card.png"
alt="imgAlt"
class="object-cover"
/>
</div>
<div class="md:ml-auto md:w-2/3 md:pl-10 px-20 text-left">
<h2 class="text-4xl font-semibold font-tf-secondary uppercase">
Projects
</h2>
<p class="mt-6 mb-8 leading-relaxed">
Organisations that take action now to shape a conscious digital
world.
</p>
<div
class="flex ml-52 duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-105"
>
<a href="/projects"
><svg
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 430.04 315.72"
class="inline-block fill-current text-green-600 h-5 w-5 mt-3"
>
<title>Arrows</title>
<path
d="M46.17,96.56l84.05,0a18.74,18.74,0,0,1,19.7,9.16L274.84,244.54a14.64,14.64,0,0,1,3.74,11,14.24,14.24,0,0,1-3.74,8.19L149.26,402.36a17.41,17.41,0,0,1-19.78,9.14l-83.7.5c-.48-.14-8.05-2.47-10.24-10.14a15.37,15.37,0,0,1,2.22-12.61L159,254.1,36.28,116.58c-.28-.65-3-7.18.79-13.43A14.9,14.9,0,0,1,46.17,96.56Z"
transform="translate(-35 -96.28)"
class="cls-1"
></path>
<path
d="M232.57,96.56l84.05,0a18.74,18.74,0,0,1,19.7,9.16L461.24,244.54a14.69,14.69,0,0,1,3.73,11,14.25,14.25,0,0,1-3.73,8.19L335.65,402.36a17.39,17.39,0,0,1-19.77,9.14l-83.71.5c-.47-.14-8-2.47-10.23-10.14a15.37,15.37,0,0,1,2.22-12.61L345.39,254.1,222.68,116.58c-.28-.65-3-7.18.79-13.43A14.9,14.9,0,0,1,232.57,96.56Z"
transform="translate(-35 -96.28)"
class="cls-1"
></path></svg
></a>
<a
href="/projects"
class="inline-block text-green-600 hover:underline py-2 ml-2 uppercase text-right font-bold"
>LEARN MORE</a
>
</div>
</div>
</div>
</section> -->
<!-- <vue-markdown> </vue-markdown> -->
<NewCard v-for="card in cards" :key="card.title" :card="card" />
<InTheNews
v-if="$page.markdownPage.inTheNews"
:news="$page.markdownPage.inTheNews"
/>
</div>
</Layout>
</template>
<script>
import VueMarkdown from "vue-markdown";
import NewCard from "~/components/NewCard.vue";
import Header from "~/components/Header.vue";
<page-query>
query {
markdownPage(id: "home") {
id
path
header_title
header_image
header_excerpt
header_altImg
button
link
inTheNews {
id
excerpt
partners {
path
logo
}
}
}
}
</page-query>
<script>
import Header from "~/components/marketing/sections/cta-sections/Header.vue";
import InTheNews from "~/components/marketing/sections/logo-clouds/off_white_grid.vue";
export default {
metaInfo: {
title: "Home",
components: {
Header,
InTheNews,
},
data() {
metaInfo() {
return {
cards: [
{
title: "PROJECTS",
content:
"Organisations that take action now to shape a conscious digital world.",
img: "background-image:url('https://fakeimg.pl/640x360')",
button: "Learn More",
link: "/projects",
},
{
title: "PEOPLE",
content:
"Independent of location, race, gender, religion we leave no one behind.",
img: "background-image:url('https://fakeimg.pl/640x360')",
button: "Learn More",
link: "/people",
},
{
title: "BLOG",
content:
"We collaborate to improve our solutions, efficiency, reach, visibility and service.",
img: "background-image:url('https://fakeimg.pl/640x360')",
button: "Learn More",
link: "/blog",
},
],
headers: [
{
title: "THANK YOU THREEFOLD MEMBERS",
img: "img/equality.png",
altImg :"home",
content:"Welcome to the growing ecosystem of ThreeFold.",
},
],
title: this.$page.markdownPage.title,
};
},
computed: {
contentHeight() {
if (process.isClient) {
return window.innerHeight - 50;
}
},
},
components: {
VueMarkdown,
NewCard,
Header,
},
};
</script>
</script>

View File

@@ -1,8 +1,20 @@
<template>
<Layout>
<FilterHeader />
<div class="container sm:pxi-0 mx-auto overflow-hidden">
<div class="flex flex-wrap with-large pt-12 mt-8 pb-8 mx-4 sm:-mx-4">
<NewsFilterHeader
@selectedTopic="setTopic"
@selectedYear="setYear"
@selectedMonth="setMonth"
@resetAll="resetAll"
:topics="topics"
:years="years"
:months="months"
/>
<div
class="container sm:pxi-0 mx-auto overflow-hidden"
:style="{ 'min-height': contentHeight + 'px' }"
>
<div class="flex flex-wrap news pt-12 mt-8 pb-8 mx-4 sm:-mx-4">
<PostListItem
:showtags="true"
v-for="edge in news.edges"
@@ -10,6 +22,9 @@
:record="edge.node"
/>
</div>
<div class="text-center" v-if="news.edges.length == 0">
<h2 class="inlibe-flex mx-auto text-gray-700 w-3/4">No results</h2>
</div>
</div>
<div class="pagination flex justify-center mb-8">
<Pagination
@@ -24,9 +39,7 @@
</template>
<page-query>
query{
entries: allNews(sortBy: "created", order: DESC) {
totalCount
pageInfo {
@@ -49,25 +62,147 @@ query{
}
}
}
topics: allNewsTag{
edges{
node{
title
}
}
}
}
</page-query>
<script>
import FilterHeader from "~/components/FilterHeader.vue";
import PostListItem from "~/components/PostListItem.vue";
import Pagination from "~/components/Pagination.vue";
import NewsFilterHeader from "~/components/custom/NewsFilterHeader.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import Pagination from "~/components/custom/Pagination.vue";
export default {
data() {
const allMonths = [
"All",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
const currYear = new Date().getFullYear();
var years = ["All"];
var r = this.range(2019, currYear);
r.forEach((year) => years.push(String(year)));
return {
selectedTopic: "All",
selectedYear: "All",
selectedMonth: "All",
months: allMonths,
years: years,
listArchive: false,
archiveButtonText: "Archive",
};
},
metaInfo: {
title: "Home",
title: "Newsroom",
},
components: {
PostListItem,
Pagination,
FilterHeader,
NewsFilterHeader,
},
methods: {
setTopic: function (topic) {
this.selectedTopic = topic;
},
setYear(year) {
this.selectedYear = year;
},
setMonth(month) {
this.selectedMonth = month;
},
resetAll() {
this.selectedTopic = "All";
this.selectedYear = "All";
this.selectedMonth = "All";
},
toggleListArchive() {
if (this.listArchive) {
this.listArchive = false;
} else {
this.listArchive = true;
}
},
// toggleArchiveButtonText() {
// if (this.archiveButtonText == "Archive") {
// this.archiveButtonText = "News";
// this.resetAll()
// } else {
// this.archiveButtonText = "Archive"
// }
// },
range(start, end, step) {
var range = [];
var typeofStart = typeof start;
var typeofEnd = typeof end;
if (step === 0) {
throw TypeError("Step cannot be zero.");
}
if (typeofStart == "undefined" || typeofEnd == "undefined") {
throw TypeError("Must pass start and end arguments.");
} else if (typeofStart != typeofEnd) {
throw TypeError("Start and end arguments must be of same type.");
}
typeof step == "undefined" && (step = 1);
if (end < start) {
step = -step;
}
if (typeofStart == "number") {
while (step > 0 ? end >= start : end <= start) {
range.push(start);
start += step;
}
} else if (typeofStart == "string") {
if (start.length != 1 || end.length != 1) {
throw TypeError("Only strings with one character are supported.");
}
start = start.charCodeAt(0);
end = end.charCodeAt(0);
while (step > 0 ? end >= start : end <= start) {
range.push(String.fromCharCode(start));
start += step;
}
} else {
throw TypeError("Only string and number types are supported");
}
return range;
},
},
computed: {
topics: function () {
var res = ["All"];
this.$page.topics.edges.forEach((edge) => res.push(edge.node.title));
return res;
},
baseurl: function () {
return "";
},
@@ -81,14 +216,43 @@ export default {
for (var i = 0; i < old.edges.length; i++) {
var node = old.edges[i].node;
const diff = Math.abs(new Date() - new Date(node.datetime));
var nodeDate = new Date(node.datetime);
const diff = Math.abs(new Date() - nodeDate);
const diffDays = Math.ceil(diff / (1000 * 60 * 60 * 24));
if (diffDays <= 30) {
res.edges.push({ node: node, id: node.id });
var selected = false;
if (!this.listArchive && diffDays <= 30) {
selected = true;
} else if (this.listArchive && diffDays > 30) {
selected = true;
}
if (!selected) continue;
// Now check topic
var topics = ["All"];
node.tags.forEach((tag) => topics.push(tag.title));
if (!topics.includes(this.selectedTopic)) continue;
// Check year
var years = ["All", String(nodeDate.getFullYear())];
if (!years.includes(this.selectedYear)) continue;
// Check Month
var months = ["All", this.months[nodeDate.getMonth() + 1]];
if (!months.includes(this.selectedMonth)) continue;
res.edges.push({ node: node, id: node.id });
}
return res;
},
contentHeight() {
if (process.isClient) {
return window.innerHeight - 570;
}
},
},
};
</script>

5
src/pages/README.md Normal file
View File

@@ -0,0 +1,5 @@
Pages are usually used for normal pages or for listing items from a GraphQL collection.
Add .vue files here to create pages. For example **About.vue** will be **site.com/about**.
Learn more about pages: https://gridsome.org/docs/pages/
You can delete this file.

View File

@@ -16,7 +16,7 @@
<div class="flex justify-between items-center">
<ul class="list-none flex author-list m-0">
<li
v-for="author in $page.blog.author"
v-for="author in $page.blog.authors"
:key="author.id"
class="author-list-item"
>
@@ -34,7 +34,7 @@
<div class="pl-3 flex flex-col text-xs leading-none uppercase">
<p>
<span
v-for="(author, index) in $page.blog.author"
v-for="(author, index) in $page.blog.authors"
:key="author.id"
>
<g-link
@@ -43,7 +43,7 @@
class="hover:underline"
>{{ author.name }}</g-link
>
<span v-if="index < $page.blog.author.length - 1">,</span>
<span v-if="index < $page.blog.authors.length - 1">,</span>
</span>
</p>
<p class="text-gray-700">
@@ -128,7 +128,7 @@
title
path
}
author {
authors {
id
name
image
@@ -142,7 +142,9 @@
image(width:800)
path
timeToRead
author {
humanTime : created(format:"DD MMMM YYYY")
datetime : created(format:"ddd MMM DD YYYY hh:mm:ss zZ")
authors {
id
name
image(width:64, height:64, fit:inside)
@@ -156,21 +158,21 @@
image(width:800)
path
timeToRead
author {
humanTime : created(format:"DD MMMM YYYY")
datetime : created(format:"ddd MMM DD YYYY hh:mm:ss zZ")
authors {
id
name
image(width:64, height:64, fit:inside)
path
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/PostListItem.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
export default {
components: {
@@ -181,6 +183,7 @@ export default {
title: this.$page.blog.title,
};
},
};
</script>

View File

@@ -1,10 +1,114 @@
<template>
<Layout :hideHeader="true" :disableScroll="true">
<div class="container sm:pxi-0 mx-auto overflow-x-hidden text-center py-5">
<vue-markdown>
{{ $page.markdownPage.content }}
</vue-markdown>
<div class="container sm:pxi-0 mx-auto overflow-x-hidden py-5">
<Header
v-if="
$page.markdownPage.id !== 'contact' &&
$page.markdownPage.header_title &&
$page.markdownPage.header_title != ''
"
:title="$page.markdownPage.header_title"
:image="$page.markdownPage.header_image"
:altImg="$page.markdownPage.header_altImg"
:excerpt="$page.markdownPage.header_excerpt"
/>
<VerticalNav
:slides="$page.markdownPage.slides"
v-if="$page.markdownPage.slides && $page.markdownPage.slides.length > 0"
/>
<NewCard
v-for="card in $page.markdownPage.cards"
:key="card.id"
:card="card"
/>
<GetInTouch
:contacts="$page.markdownPage.contactData"
v-if="$page.markdownPage.contactData.length > 0"
/>
<SolutionsHeader
v-if="$page.markdownPage.header"
:header="$page.markdownPage.header"
/>
<ShowcaseProducts
:main="$page.markdownPage.productMain"
:products="$page.markdownPage.productData"
v-if="
$page.markdownPage.productData &&
$page.markdownPage.productData.length > 0
"
/>
<HowItWorks
v-if="$page.markdownPage.howItWorks.length > 0"
:HIWData="$page.markdownPage.howItWorks"
:main="$page.markdownPage.howItWorksMain"
/>
<template>
<ClientOnly>
<Features
v-if="$page.markdownPage.features.length > 0"
:main="$page.markdownPage.featuresMain"
:features="$page.markdownPage.features"
/>
</ClientOnly>
</template>
<logoShowcase
v-if="$page.markdownPage.logos.length > 0"
:logos="$page.markdownPage.logos"
/>
<template>
<ClientOnly>
<CallToAction
v-if="$page.markdownPage.cta"
:cta="$page.markdownPage.cta"
/>
<SignUp
v-if="$page.markdownPage.signup"
:signup="$page.markdownPage.signup"
/>
</ClientOnly>
</template>
<template>
<ClientOnly>
<Comparison
v-if="
$page.markdownPage.comparisonSecs &&
$page.markdownPage.comparisonSecs.length > 0
"
:main="$page.markdownPage.comparisonMain"
:sections="$page.markdownPage.comparisonSecs"
/>
</ClientOnly>
</template>
<Roadmap
v-if="$page.markdownPage.roadmap.length > 0"
:roadmap="$page.markdownPage.roadmap"
/>
<FourTiersWithToggle
v-if="$page.markdownPage.pricingPlans.length > 0"
:main="$page.markdownPage.pricing_plansMain"
:pricingPlans="$page.markdownPage.pricingPlans"
/>
<WithComparisonTable
v-if="$page.markdownPage.plans.length > 0"
:plans="$page.markdownPage.plans"
/>
<BrandPanel
:brand="$page.markdownPage.brandPanel"
v-if="$page.markdownPage.brandPanel"
/>
</div>
</Layout>
</template>
@@ -12,30 +116,245 @@
<page-query>
query($id: ID!) {
markdownPage(id: $id) {
id
path
content
title
}
excerpt
header_excerpt
header_altImg
header_title
header_image
slides{
id
title
excerpt
image
order
}
cards{
id
title
image
button
link
order
excerpt
}
contactData{
id
title
mail
phone
}
header{
title
subtitle
excerpt
btn1
link1
btn2
link2
}
howItWorks{
id
title
excerpt
}
howItWorksMain{
id
title
image
}
productMain{
id
subtitle
title
}
productData{
id
title
excerpt
}
brandPanel{
id
title
subtitle
excerpt(length: 2000)
sourceUrl
btnTxt
image
}
featuresMain{
id
title
btn
link
excerpt
}
logos{
id
image
}
features{
id
title
svg
excerpt
}
cta{
id
title
excerpt
button
link
}
signup{
id
title
button1
link1
button2
link2
}
comparisonMain{
id
title
description
button
link
}
comparisonSecs{
id
svg
title
excerpt
}
roadmap{
id
title
excerpt
}
pricing_plansMain{
id
title
button1
button2
excerpt
}
pricingPlans{
id
title
excerpt
price
duration
button
link
includeTitle
options
}
plans{
id
title
rows {
title
firstCol
secCol
thirdCol
}
}
}
}
</page-query>
<script>
import VueMarkdown from 'vue-markdown'
import NewCard from "~/components/marketing/sections/cta-sections/NewCard.vue";
import Header from "~/components/marketing/sections/cta-sections/Header.vue";
import VerticalNav from "~/components/custom/Navbar/VerticalNav.vue";
import GetInTouch from "~/components/custom/Navbar/Getintouch.vue";
import SolutionsHeader from "~/components/custom/sections/header/HeaderSection.vue";
import HowItWorks from "~/components/custom/sections/HowItWorks.vue";
import ShowcaseProducts from "~/components/marketing/sections/cta-sections/ShowcaseProducts.vue";
import Features from "~/components/custom/sections/Features.vue";
import logoShowcase from "~/components/marketing/sections/cta-sections/logoShowcase.vue";
import CallToAction from "~/components/custom/sections/CallToAction.vue";
import SignUp from "~/components/custom/sections/SignUp.vue";
import Comparison from "~/components/custom/sections/Comparison.vue";
import Roadmap from "~/components/custom/sections/Roadmap.vue";
import FourTiersWithToggle from "~/components/marketing/sections/pricing/four_tiers_with_toggle.vue";
import WithComparisonTable from "~/components/marketing/sections/pricing/with_comparison_table.vue";
import BrandPanel from "~/components/marketing/sections/cta-sections/BrandPanel.vue";
export default {
components: {
VueMarkdown
NewCard,
Header,
VerticalNav,
GetInTouch,
SolutionsHeader,
HowItWorks,
ShowcaseProducts,
Features,
logoShowcase,
CallToAction,
SignUp,
Comparison,
Roadmap,
FourTiersWithToggle,
WithComparisonTable,
BrandPanel,
},
metaInfo() {
return {
title: this.$page.markdownPage.title,
};
},
mounted() {
// console.log(this.$page.markdownPage.plans);
},
};
</script>
<style scoped>
/* h2 {
padding-bottom: 8rem;
} */
/**
* Add back the container background-color, border-radius, padding, margin
* and overflow that we removed from <pre>.
*/
.gridsome-highlight {
background-color: #fdf6e3;
border-radius: 0.3em;
margin: 0.5em 0;
padding: 1em;
overflow: auto;
}
.gridsome-highlight-code-line {
background-color: #feb;
display: block;
margin-right: -1em;
margin-left: -1em;
padding-right: 1em;
padding-left: 0.75em;
border-left: 0.25em solid #f99;
}
/**
* Remove the default PrismJS theme background-color, border-radius, margin,
* padding and overflow.
* 1. Make the element just wide enough to fit its content.
* 2. Always fill the visible space in .gatsby-highlight.
* 3. Adjust the position of the line numbers
*/
.gridsome-highlight pre[class*="language-"] {
background-color: transparent;
margin: 0;
padding: 0;
overflow: initial;
float: left; /* 1 */
min-width: 100%; /* 2 */
}
/* Adjust the position of the line numbers */
.gridsome-highlight pre[class*="language-"].line-numbers {
padding-left: 2.8em;
}
</style> >

View File

@@ -1,12 +1,12 @@
<template>
<Layout :hideHeader="true" :disableScroll="true">
<div class="container sm:pxi-0 mx-auto overflow-x-hidden">
<TagFilterHeader :tags="memberships" :selected="$page.membership.title" v-if="$page.allMembership.edges.length > 1"/>
<div class="container sm:pxi-0 mx-auto mt-8 overflow-x-hidden">
<div class="mx-4 sm:mx-0">
<h1 class="pb-0 mb-0 text-5xl font-medium capitalize">
{{ $page.membership.title }}
</h1>
<p class="text-gray-700 text-xl">
<span class="self-center"
>{{ $page.membership.belongsTo.totalCount }} People</span
>
@@ -58,15 +58,38 @@
}
}
}
allMembership(filter: {title: {in: ["foundation", "tech"]}}){
edges{
node{
id
title
path
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/PostListItem.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import TagFilterHeader from "~/components/custom/TagFilterHeader.vue";
export default {
components: {
PostListItem,
TagFilterHeader,
},
computed: {
memberships() {
var res = [{ title: "All", path: "/team" }];
this.$page.allMembership.edges.forEach((edge) =>
res.push({ title: edge.node.title, path: edge.node.path })
);
return res;
},
},
metaInfo() {

View File

@@ -16,7 +16,7 @@
<div class="flex justify-between items-center">
<ul class="list-none flex author-list m-0">
<li
v-for="author in $page.news.author"
v-for="author in $page.news.authors"
:key="author.id"
class="author-list-item"
>
@@ -128,7 +128,7 @@
title
path
}
author {
authors {
id
name
image
@@ -142,7 +142,7 @@
image(width:800)
path
timeToRead
author {
authors {
id
name
image(width:64, height:64, fit:inside)
@@ -156,7 +156,7 @@
image(width:800)
path
timeToRead
author {
authors {
id
name
image(width:64, height:64, fit:inside)
@@ -170,7 +170,8 @@
</page-query>
<script>
import PostListItem from "~/components/PostListItem.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
export default {
components: {

View File

@@ -0,0 +1,74 @@
<template>
<Layout>
<TagFilterHeader :tags="tags" selected="all" v-if="$page.tags.edges.length > 1"/>
<div class="container mt-8 sm:pxi-0 mx-auto overflow-x-hidden">
<div class="flex flex-wrap with-large pt-8 pb-8 mx-4 sm:-mx-4">
<PostListItem
v-for="partner in $page.entries.edges"
:key="partner.id"
:record="partner.node"
pathPrefix="/partners"
/>
</div>
</div>
</Layout>
</template>
<page-query>
query ($private: Int){
entries: allProject (sortBy: "rank", order: DESC, filter: { private: { ne: $private }, tags: { id: {in: ["farming"]}}}){
totalCount
edges {
node {
id
title
path
members {
id
name
image(width:64, height:64, fit:inside)
path
},
rank
linkedin
excerpt
image(width:800)
timeToRead
logo
}
}
}
tags: allProjectTag (filter: { title: {in: ["farming"]}}) {
edges{
node{
id
title
path
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import TagFilterHeader from "~/components/custom/TagFilterHeader.vue";
export default {
components: {
PostListItem,
TagFilterHeader,
},
computed: {
tags() {
var res = [{ title: "All", path: "/partners" }];
this.$page.tags.edges.forEach((edge) =>
res.push({ title: edge.node.title, path: edge.node.path })
);
return res;
},
},
};
</script>

View File

@@ -33,7 +33,7 @@
<div class="flex justify-between items-center">
<ul class="list-none flex author-list m-0 py-2">
<li
v-for="project in $page.person.project_ids"
v-for="project in $page.person.projects"
:key="project.id"
class="author-list-item"
>
@@ -92,7 +92,7 @@
title
path
}
project_ids{
projects{
id
title
path
@@ -123,7 +123,7 @@
timeToRead
humanTime : created(format:"DD MMM YYYY")
datetime : created
author {
authors {
id
name
image(width:64, height:64, fit:inside)
@@ -137,20 +137,28 @@
image(width:800)
logo
path
humanTime : startdate(format:"DD MMM YYYY")
datetime : created
}
}
}
}
}
}
memberships: allMembership(filter: {title: {in: ["foundation", "tech"]}}){
edges{
node{
id
title
path
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/PostListItem.vue";
import Pagination from "~/components/Pagination.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import Pagination from "~/components/custom/Pagination.vue";
export default {
components: {
@@ -162,6 +170,18 @@ export default {
var pluralize = require("pluralize");
return pluralize("post", this.$page.person.belongsTo.totalCount);
},
memberships(){
var all = []
this.$page.memberships.edges.forEach((edgs) => all.push(edge.node.title))
var res = []
this.$page.person.memberships.forEach(function(membership){
if (all.includes(membership.title)){
res.push(membership)
}
});
return res
}
},
metaInfo() {
return {

View File

@@ -50,11 +50,11 @@
</section>
<section class="post-tags container mx-auto relative py-5">
<g-link
v-for="tag in $page.project.tags"
:key="tag.id"
:to="tag.path"
v-for="edge in $page.tags.edges"
:key="edge.node.id"
:to="edge.node.path"
class="text-xs bg-transparent hover:text-blue-700 py-2 px-4 mr-2 border hover:border-blue-500 border-gray-600 text-gray-700 rounded-full"
>{{ tag.title }}</g-link
>{{ edge.node.title }}</g-link
>
</section>
</div>
@@ -123,7 +123,7 @@
name
image(width:64, height:64, fit:inside)
path
project_ids{
projects{
id
title
path
@@ -135,12 +135,26 @@
}
}
}
tags: allProjectTag (filter: { title: {in: ["farming"]}}) {
edges{
node{
id
title
path
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/PostListItem.vue";
import Pagination from "~/components/Pagination.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import Pagination from "~/components/custom/Pagination.vue";
export default {
components: {

7
src/templates/README.md Normal file
View File

@@ -0,0 +1,7 @@
Templates for **GraphQL collections** should be added here.
To create a template for a collection called `WordPressPost`
create a file named `WordPressPost.vue` in this folder.
Learn more: https://gridsome.org/docs/templates/
You can delete this file.

View File

@@ -7,7 +7,7 @@
<img
v-if="loading"
class="m-auto"
src="../assets/imgs/loader.gif"
src="/img/loader.gif"
alt=""
/>
<div
@@ -30,7 +30,7 @@
<page-query>
query ($private: Int){
projects: allProject (filter: { private: { ne: $private }}){
projects: allProject (filter: { private: { ne: $private }, tags: { id: {in: ["farming"]}}}){
edges {
node {
id
@@ -52,7 +52,7 @@ query ($private: Int){
image(width:800)
path
timeToRead
author {
authors {
id
image(width:64, height:64, fit:inside)
@@ -62,7 +62,7 @@ query ($private: Int){
}
}
people: allPerson(filter: { private: { ne: $private }}) {
people: allPerson(filter: { private: { ne: $private }, memberships: { id: {in: ["foundation", "tech"]}}}) {
edges {
node {
id
@@ -96,7 +96,7 @@ query ($private: Int){
path
humanTime : created(format:"DD MMM YYYY")
datetime : created
author {
authors {
id
name
image(width:64, height:64, fit:inside)
@@ -106,12 +106,24 @@ query ($private: Int){
}
}
markdowns: allMarkdownPage{
edges{
node{
__typename
header_title
header_excerpt
path
title
excerpt
}
}
}
}
</page-query>
<script>
import SearchListItem from "~/components/SearchListItem.vue";
import SearchListItem from "~/components/custom/Cards/SearchListItem.vue";
export default {
metaInfo: {
@@ -125,8 +137,8 @@ export default {
computed: {
searchResults() {
const searchTerm = this.q;
if (searchTerm.length < 3) return [];
var searchRes = this.$search.search({ query: searchTerm, limit: 5 });
if (!searchTerm || searchTerm.length < 3) return [];
var searchRes = this.$search.search({ query: searchTerm, limit: 100 });
var result = [];
for (var i = 0; i < searchRes.length; i++) {
var item = searchRes[i];
@@ -157,6 +169,12 @@ export default {
var item = this.$page.blogs.edges[i];
this.objects[item.node.path] = item.node;
}
for (var i = 0; i < this.$page.markdowns.edges.length; i++) {
var item = this.$page.markdowns.edges[i];
this.objects[item.node.path] = item.node;
}
this.loading = false;
},
components: {

View File

@@ -1,12 +1,15 @@
<template>
<Layout :hideHeader="true" :disableScroll="true">
<div class="container sm:pxi-0 mx-auto overflow-x-hidden pt-24">
<TagFilterHeader :tags="tagTitles" :selected="title" v-if="tagTitles.length > 2"/>
<div class="container sm:px-0 mx-auto overflow-x-hidden pt-12">
<div class="mx-4 sm:mx-0">
<h1 class="pb-0 mb-0 text-5xl font-medium">{{ tags.title }}</h1>
<h1 class="pb-0 mb-0 text-5xl font-medium capitalize">
{{ tags.title }}
</h1>
<p class="text-gray-700 text-xl">
<span
class="self-center"
>{{ tags.belongsTo.totalCount }} {{item}}</span>
<span class="self-center"
>{{ tags.belongsTo.totalCount }} {{ item }}</span
>
</p>
</div>
@@ -46,21 +49,6 @@
}
edges {
node {
... on Blog {
title
excerpt
image(width:800)
path
timeToRead
humanTime : created(format:"DD MMM YYYY")
datetime : created
author {
id
name
image(width:64, height:64, fit:inside)
path
}
},
... on Project {
title
excerpt
@@ -94,55 +82,151 @@
timeToRead
humanTime : created(format:"DD MMM YYYY")
datetime : created
author {
authors {
id
name
image(width:64, height:64, fit:inside)
path
}
},
... on Project {
title
excerpt
image(width:800)
path
humanTime : startdate(format:"DD MMM YYYY")
datetime : created
}
}
}
}
}
}
blogTag(id: $id) {
title
path
belongsTo{
totalCount
pageInfo {
totalPages
currentPage
}
edges {
node {
... on Blog {
title
excerpt
image(width:800)
path
timeToRead
humanTime : created(format:"DD MMM YYYY")
datetime : created
authors {
id
name
image(width:64, height:64, fit:inside)
path
}
}
}
}
}
}
allProjectTag(filter: { title: {in: ["farming"]}}){
edges{
node{
id
title
path
}
}
}
allNewsTag{
edges{
node{
id
title
path
}
}
}
allBlogTag{
edges{
node{
id
title
path
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/PostListItem.vue";
import Pagination from "~/components/Pagination.vue";
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import Pagination from "~/components/custom/Pagination.vue";
import TagFilterHeader from "~/components/custom/TagFilterHeader.vue";
export default {
components: {
Pagination,
PostListItem
PostListItem,
TagFilterHeader,
},
computed:{
tags(){
return this.$page.projectTag || this.$page.newsTag
computed: {
title() {
return this.tags.title;
},
item(){
var plural = this.tags.belongsTo.totalCount > 0
return this.$page.projectTag? plural? "projects" : "project" : "news"
}
tagTitles() {
var path = "";
var tags = null;
if (this.$page.projectTag) {
path = "/partners";
tags = this.$page.allProjectTag;
} else if (this.$page.newsTag) {
path = "/news";
tags = this.$page.allNewsTag;
} else if (this.$page.blogTag) {
path = "/blog";
tags = this.$page.allBlogTag;
}
var res = [{ title: "All", path: path }];
tags.edges.forEach((edge) =>
res.push({ title: edge.node.title, path: edge.node.path })
);
return res;
},
tags() {
return this.$page.projectTag || this.$page.newsTag || this.$page.blogTag;
},
item() {
var plural = this.tags.belongsTo.totalCount > 0;
if (this.$page.projectTag) {
if (plural) return "projects";
return "project";
}
if (this.$page.newsTag) {
if (plural) return "posts";
return "post";
}
if (this.$page.blogTag) {
if (plural) return "posts";
return "post";
}
},
},
mounted() {
document.addEventListener("click", this.close);
},
beforeDestroy() {
document.removeEventListener("click", this.close);
},
metaInfo() {
return {
title: this.tags.title
title: this.tags.title,
};
}
},
};
</script>

69
src/templates/Team.vue Normal file
View File

@@ -0,0 +1,69 @@
<template>
<Layout>
<TagFilterHeader :tags="memberships" selected="all" v-if="$page.memberships.edges.length > 1"/>
<div class="container sm:pxi-0 mx-auto mt-8 overflow-x-hidden">
<div class="flex flex-wrap with-large pt-8 pb-8 mx-4 sm:-mx-4">
<PostListItem
v-for="person in $page.entries.edges"
:key="person.id"
:record="person.node"
/>
</div>
</div>
</Layout>
</template>
<page-query>
query ($private: Int){
entries: allPerson (sortBy: "rank", order: DESC, filter: { private: { ne: $private }, memberships: { id: {in: ["foundation", "tech"]}}}){
totalCount
edges {
node {
path
content
excerpt
name
rank
bio
linkedin
websites
countries
cities
image(width:800)
private
}
}
}
memberships: allMembership(filter: {title: {in: ["foundation", "tech"]}}){
edges{
node{
id
title
path
}
}
}
}
</page-query>
<script>
import PostListItem from "~/components/custom/Cards/PostListItem.vue";
import TagFilterHeader from "~/components/custom/TagFilterHeader.vue";
export default {
components: {
PostListItem,
TagFilterHeader,
},
computed: {
memberships() {
var res = [{ title: "All", path: "/team" }];
this.$page.memberships.edges.forEach((edge) =>
res.push({ title: edge.node.title, path: edge.node.path })
);
return res;
},
},
};
</script>