Skip to content
This repository was archived by the owner on Dec 18, 2022. It is now read-only.

Commit f121508

Browse files
committed
Add dynamic pages
1 parent 6ed199d commit f121508

File tree

4 files changed

+152
-59
lines changed

4 files changed

+152
-59
lines changed

components/layout/Header.vue

Lines changed: 85 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,90 @@
44
<div
55
class="flex justify-between items-center py-2 flex-wrap lg:py-6 lg:space-x-10"
66
>
7-
<div class="flex justify-between w-full lg:w-auto">
7+
<div v-if="logo" class="flex justify-between w-full lg:w-auto">
88
<nuxt-link :to="localePath('/')" class="logo">
9-
<img
10-
class="h-8 w-auto sm:h-10"
11-
src="@/assets/images/logo_landscape_white.png"
12-
alt="Logo"
13-
/>
9+
<img class="h-8 w-auto sm:h-10" :src="logo" alt="Logo" />
1410
</nuxt-link>
1511
</div>
1612
<nav
13+
v-if="menu"
1714
class="lg:flex lg:flex-1 lg:justify-center lg:space-x-10 mt-2 lg:mt-0 w-screen lg:max-w-screen-md overflow-x-scroll overscroll-y-none whitespace-nowrap"
1815
>
19-
<nuxt-link
20-
v-for="menuItem in menu"
21-
:key="menuItem.text"
22-
:to="localePath(menuItem.link)"
23-
class="text-base font-medium text-white hover:text-primary-700 text-center hover:border-primary-700 mr-3 lg:mr-0"
24-
>
25-
{{ $t(menuItem.text) }}
26-
</nuxt-link>
16+
<template v-for="item in menu">
17+
<nuxt-link
18+
v-if="item.link.linktype === 'story'"
19+
:key="item.name"
20+
:to="localePath(`/${item.link.url || item.link.cached_url}`)"
21+
:target="item.target"
22+
class="text-base font-medium text-white hover:text-primary-700 text-center hover:border-primary-700 mr-3 lg:mr-0"
23+
>
24+
{{ item.name }}
25+
</nuxt-link>
26+
27+
<a
28+
v-else
29+
:key="item.name"
30+
:target="item.target"
31+
:href="item.link.url || item.link.cached_url"
32+
class="text-base font-medium text-white hover:text-primary-700 text-center hover:border-primary-700 mr-3 lg:mr-0"
33+
>
34+
{{ item.name }}
35+
</a>
36+
</template>
2737
</nav>
38+
<div
39+
v-if="availableLocales && availableLocales.length > 0"
40+
class="flex items-center justify-end absolute right-0 top-1 lg:relative lg:w-0"
41+
>
42+
<t-dropdown
43+
:fixedClasses="{
44+
button:
45+
'block px-4 py-2 text-white transition duration-100 ease-in-out bg-blue-500 border border-transparent rounded shadow-sm hover:bg-blue-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50 disabled:opacity-50 disabled:cursor-not-allowed',
46+
wrapper: 'inline-flex flex-col',
47+
dropdownWrapper: 'relative z-10',
48+
dropdown:
49+
'origin-top-right absolute right-0 w-24 rounded shadow bg-white mt-1',
50+
enterClass: 'opacity-0 scale-95',
51+
enterActiveClass: 'transition transform ease-out duration-100',
52+
enterToClass: 'opacity-100 scale-100',
53+
leaveClass: 'opacity-100 scale-100',
54+
leaveActiveClass: 'transition transform ease-in duration-75',
55+
leaveToClass: 'opacity-0 scale-95'
56+
}"
57+
>
58+
<div
59+
slot="trigger"
60+
slot-scope="{
61+
mousedownHandler,
62+
focusHandler,
63+
blurHandler,
64+
keydownHandler
65+
}"
66+
class="flex"
67+
>
68+
<t-button
69+
variant="outline-secondary"
70+
@mousedown="mousedownHandler"
71+
@focus="focusHandler"
72+
@blur="blurHandler"
73+
@keydown="keydownHandler"
74+
class="text-white"
75+
>
76+
<TranslateIcon class="w-4" />
77+
</t-button>
78+
</div>
79+
80+
<div class="py-1 rounded-md shadow-xs">
81+
<nuxt-link
82+
v-for="locale in availableLocales"
83+
:key="locale.code"
84+
:to="switchLocalePath(locale.code)"
85+
class="block px-4 py-2 text-sm leading-5 text-gray-700 transition duration-150 ease-in-out hover:bg-gray-100 focus:outline-none focus:bg-gray-100"
86+
>{{ locale.name }}</nuxt-link
87+
>
88+
</div>
89+
</t-dropdown>
90+
</div>
2891
</div>
2992
</div>
3093
</header>
@@ -38,19 +101,15 @@ export default {
38101
TranslateIcon
39102
},
40103
data(context) {
41-
console.log(context.$store.state.menu.items);
42-
console.log(context.$store.state.menu.logo);
104+
return {
105+
menu: context.$store.state.menu.items,
106+
logo: context.$store.state.menu.logo
107+
};
43108
},
44-
setup() {
45-
const menu = [
46-
// { link: 'projects', text: 'menu.projects' },
47-
{ link: 'collaborate', text: 'menu.collaborate' },
48-
{ link: 'team', text: 'menu.team' },
49-
// { link: 'articles', text: 'menu.articles' },
50-
{ link: 'contact', text: 'menu.contact' }
51-
];
52-
53-
return { menu };
109+
computed: {
110+
availableLocales() {
111+
return this.$i18n.locales.filter((i) => i.code !== this.$i18n.locale);
112+
}
54113
}
55114
};
56115
</script>

helpers/common-page.helper.js

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ export function onStoryBridgeChangedToPublishedRefreshPage(context) {
1818
}
1919

2020
export function loadPageContentFromApi(context, route, starts_with) {
21-
// Load the JSON from the API
21+
const url = route;
22+
2223
return context.app.$storyapi
23-
.get(route, {
24+
.get(url, {
2425
version: 'published',
2526
starts_with: starts_with
2627
})
@@ -45,34 +46,52 @@ export function loadPageContentFromApi(context, route, starts_with) {
4546
}
4647

4748
export function loadMenuFromApi(context) {
48-
if (context.store.state.menu.items.length === 0) {
49-
return context.app.$storyapi
50-
.get(`cdn/stories/`, {
51-
starts_with: context.localePath('menu'),
52-
version: 'published'
53-
})
54-
.then((menuRefResponse) => {
55-
const stories = menuRefResponse.data.stories;
56-
const logo = stories && stories[0].content.logo;
57-
const items = stories && stories[0].content.items;
58-
59-
context.store.commit('menu/setMenu', items);
60-
context.store.commit('menu/setLogo', logo.filename);
61-
})
62-
.catch((res) => {
63-
if (!res.response) {
64-
console.error(res);
65-
context.error({
66-
statusCode: 404,
67-
message: 'Failed to receive content form api'
68-
});
69-
} else {
70-
console.error(res.response.data);
71-
context.error({
72-
statusCode: res.response.status,
73-
message: res.response.data
74-
});
75-
}
76-
});
49+
if (context.store.state.menu.items.length !== 0) {
50+
return Promise.resolve(context.store.state.menu.items);
7751
}
52+
53+
return context.app.$storyapi
54+
.get(`cdn/stories/`, {
55+
starts_with: context.localePath('menu'),
56+
version: 'published'
57+
})
58+
.then((menuRefResponse) => {
59+
const stories = menuRefResponse.data.stories;
60+
const logo = stories && stories[0].content.logo;
61+
const items = stories && stories[0].content.items;
62+
63+
context.store.commit('menu/setMenu', items);
64+
context.store.commit('menu/setLogo', logo.filename);
65+
66+
return items;
67+
})
68+
.catch((res) => {
69+
if (!res.response) {
70+
console.error(res);
71+
context.error({
72+
statusCode: 404,
73+
message: 'Failed to receive content form api'
74+
});
75+
} else {
76+
console.error(res.response.data);
77+
context.error({
78+
statusCode: res.response.status,
79+
message: res.response.data
80+
});
81+
}
82+
});
83+
}
84+
85+
export function loadPageContent(context, path) {
86+
return loadMenuFromApi(context).then((menu) => {
87+
const item = menu.find(
88+
({ link }) => link.url === `${path}/` || link.cached_url === `${path}/`
89+
);
90+
const url = item ? `${path}/` : path;
91+
92+
return loadPageContentFromApi(
93+
context,
94+
`cdn/stories/${context.localePath(url)}`
95+
);
96+
});
7897
}

plugins/story-components.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import TeamMember from '../components/team/TeamMember.vue';
2020
import Teaser from '../components/Teaser.vue';
2121

2222
Vue.component('page', Page);
23-
Vue.component('content-project', Project);
24-
Vue.component('content-article', Article);
23+
Vue.component('project', Project);
24+
Vue.component('article', Article);
2525
Vue.component('teaser', Teaser);
2626
Vue.component('grid', Grid);
2727
Vue.component('feature', Feature);

yarn.lock

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4632,6 +4632,21 @@ component-emitter@^1.2.1:
46324632
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
46334633
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
46344634

4635+
components-helpdev-storyblok@HelpDev/Storyblok-Components#1.0.7:
4636+
version "1.0.1"
4637+
resolved "https://codeload.github.com/HelpDev/Storyblok-Components/tar.gz/cbc2514af8afd7700418330b16fc83ac1a608630"
4638+
dependencies:
4639+
"@nuxtjs/svg" "^0.1.12"
4640+
"@tailwindcss/aspect-ratio" "^0.2.0"
4641+
"@tailwindcss/forms" "^0.3.2"
4642+
"@tailwindcss/typography" "^0.4.0"
4643+
"@vue/composition-api" "^1.0.0-rc.6"
4644+
heroicons "^1.0.0"
4645+
nuxt "^2.15.4"
4646+
nuxt-i18n "^6.24.0"
4647+
simple-icons "^4.19.0"
4648+
vue-tailwind "^2.1.7"
4649+
46354650
compressible@~2.0.16:
46364651
version "2.0.18"
46374652
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"

0 commit comments

Comments
 (0)