diff options
Diffstat (limited to 'components')
27 files changed, 611 insertions, 104 deletions
diff --git a/components/Buttons/PlainButton.stories.js b/components/Buttons/PlainButton.stories.js new file mode 100644 index 0000000..43efa24 --- /dev/null +++ b/components/Buttons/PlainButton.stories.js @@ -0,0 +1,18 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../../.storybook/decorators' + +import PlainButton from './PlainButton' + +const plainButton = { + text: 'Plain Button' +} + +storiesOf('Buttons/PlainButton', module) + .addDecorator(center) + .add('default', () => { + return { + components: { PlainButton }, + template: `<plain-button :text="text" />`, + data: () => plainButton + } + }) diff --git a/components/Buttons/PlainButton.vue b/components/Buttons/PlainButton.vue new file mode 100644 index 0000000..0bf57cc --- /dev/null +++ b/components/Buttons/PlainButton.vue @@ -0,0 +1,34 @@ +<template> + <button class="button" @click="$emit('click')">{{ text }}</button> +</template> + +<script> +export default { + name: 'PlainButton', + props: { + text: { + type: String, + required: true + } + } +} +</script> + +<style scoped> +.button { + background-color: #507b34; + padding: 10px; + max-width: 150px; + border: none; + + cursor: pointer; + + color: #ffffff; + text-align: center; + font: 16px 'Roboto Slab'; +} + +.button:hover { + background-color: #42642b; +} +</style> diff --git a/components/Facebook/FacebookFeed.stories.js b/components/Facebook/FacebookFeed.stories.js new file mode 100644 index 0000000..d9ec30a --- /dev/null +++ b/components/Facebook/FacebookFeed.stories.js @@ -0,0 +1,13 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../../.storybook/decorators' + +import FacebookFeed from './FacebookFeed' + +storiesOf('Facebook/FacebookFeed', module) + .addDecorator(center) + .add('default', () => { + return { + components: { FacebookFeed }, + template: `<facebook-feed />` + } + }) diff --git a/components/FacebookFeed.vue b/components/Facebook/FacebookFeed.vue index 9d2d251..56172f4 100644 --- a/components/FacebookFeed.vue +++ b/components/Facebook/FacebookFeed.vue @@ -1,12 +1,12 @@ <template> <section class="feed"> <h1>Zobacz co się dzieje!</h1> - <FacebookFindUsButton /> + <facebook-find-us-button /> </section> </template> <script> -import FacebookFindUsButton from "./FacebookFindUsButton.vue"; +import FacebookFindUsButton from './FacebookFindUsButton.vue' export default { components: { @@ -15,11 +15,15 @@ export default { props: { pageId: String } -}; +} </script> <style scoped> .feed { margin: 50px 0; } + +.feed > h1 { + text-align: center; +} </style> \ No newline at end of file diff --git a/components/Facebook/FacebookFindUsButton.stories.js b/components/Facebook/FacebookFindUsButton.stories.js new file mode 100644 index 0000000..e6a298b --- /dev/null +++ b/components/Facebook/FacebookFindUsButton.stories.js @@ -0,0 +1,13 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../../.storybook/decorators' + +import FacebookFindUsButton from './FacebookFindUsButton' + +storiesOf('Facebook/FacebookFindUsButton', module) + .addDecorator(center) + .add('default', () => { + return { + components: { FacebookFindUsButton }, + template: `<facebook-find-us-button />` + } + }) diff --git a/components/Facebook/FacebookFindUsButton.vue b/components/Facebook/FacebookFindUsButton.vue new file mode 100644 index 0000000..b955b0b --- /dev/null +++ b/components/Facebook/FacebookFindUsButton.vue @@ -0,0 +1,48 @@ +<template> + <a + class="button" + href="https://facebook.com/19pdhpuszcza" + target="_blank" + rel="noopener" + > + <div class="button-container"> + <img + class="image" + src="/assets/social/find_us_fb.png" + alt="Find us on Facebook" + /> + </div> + </a> +</template> + +<style scoped> +.button { + margin: 10px; +} + +.button:hover .button-container { + background-color: #efefef; +} + +.button-container { + border: 2px solid #c4c4c4; + border-radius: 4px; + padding: 15px 40px; +} + +.image { + width: 200px; + display: block; + margin: auto; +} + +@media (max-width: 500px) { + a { + width: 100%; + } + + .image { + width: 150px; + } +} +</style> diff --git a/components/FacebookFindUsButton.vue b/components/FacebookFindUsButton.vue deleted file mode 100644 index 9a27c11..0000000 --- a/components/FacebookFindUsButton.vue +++ /dev/null @@ -1,35 +0,0 @@ -<template> - <a href="https://facebook.com/19pdhpuszcza" target="_blank" rel="noopener"> - <div class="button"> - <img class="image" src="/assets/social/find_us_fb.png" alt="Find us on Facebook" /> - </div> - </a> -</template> - -<style scoped> -.button { - border: 2px solid #c4c4c4; - border-radius: 4px; - - padding: 15px 40px; - margin: 10px; -} - -.button:hover { - background-color: #efefef; -} - -.image { - width: 200px; -} - -@media (max-width: 500px) { - a { - width: 100%; - } - - .image { - width: 150px; - } -} -</style> \ No newline at end of file diff --git a/components/JoinUs.stories.js b/components/JoinUs.stories.js new file mode 100644 index 0000000..81bf934 --- /dev/null +++ b/components/JoinUs.stories.js @@ -0,0 +1,16 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../.storybook/decorators' + +import JoinUs from './JoinUs' + +const joinUs = {} + +storiesOf('JoinUs', module) + .addDecorator(center) + .add('default', () => { + return { + components: { JoinUs }, + template: `<join-us />`, + data: () => joinUs + } + }) diff --git a/components/JoinUs.vue b/components/JoinUs.vue index f534d22..d8bfadf 100644 --- a/components/JoinUs.vue +++ b/components/JoinUs.vue @@ -4,13 +4,22 @@ <div class="title"> <div class="text">Rozpocznij swoją harcerską przygodę!</div> </div> - <div class="button"> - <router-link to="/kontakt">Dołącz do nas!</router-link> - </div> + <plain-button @click="$router.push('/kontakt')" text="Dołącz do nas" /> </div> </section> </template> +<script> +import PlainButton from './Buttons/PlainButton' + +export default { + name: 'JoinUs', + components: { + PlainButton + } +} +</script> + <style scoped> .joinus { width: 100%; @@ -53,10 +62,11 @@ background-color: #507b34; padding: 10px; max-width: 150px; + color: #ffffff; + text-align: center; } .button a { - color: #ffffff; text-decoration: none; } diff --git a/components/NavLink.stories.js b/components/NavLink.stories.js new file mode 100644 index 0000000..44fe6ae --- /dev/null +++ b/components/NavLink.stories.js @@ -0,0 +1,19 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../.storybook/decorators' + +import NavLink from './NavLink' + +const navLink = { + name: 'Test', + link: '/test' +} + +storiesOf('NavLink', module) + .addDecorator(center) + .add('default', () => { + return { + components: { NavLink }, + template: `<nav-link :name="name" :link="link" />`, + data: () => navLink + } + }) diff --git a/components/NavLink.vue b/components/NavLink.vue index bb86ef8..0418172 100644 --- a/components/NavLink.vue +++ b/components/NavLink.vue @@ -9,10 +9,22 @@ <script> export default { props: { - link: String, - name: String, - external: { type: Boolean, default: false }, - pure: { type: Boolean, default: false } + link: { + type: String, + required: true + }, + name: { + type: String, + required: true + }, + external: { + type: Boolean, + default: false + }, + pure: { + type: Boolean, + default: false + } } } </script> diff --git a/components/Posts/PostLink.stories.js b/components/Posts/PostLink.stories.js new file mode 100644 index 0000000..9b12c29 --- /dev/null +++ b/components/Posts/PostLink.stories.js @@ -0,0 +1,21 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../../.storybook/decorators' + +import PostLink from './PostLink' + +export const postLink = { + title: 'Test PostLink', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pulvinar non ex non sagittis. Quisque in enim tellus. Aliquam consequat mi id sapien congue, sit amet vulputate tortor viverra. Donec.', + route: '/kronika/2019/20/11/test' +} + +storiesOf('Posts/PostLink', module) + .addDecorator(center) + .add('default', () => { + return { + components: { PostLink }, + template: `<post-link :title="title" :description="description" :route="route"/>`, + data: () => postLink + } + }) diff --git a/components/ChroniclePost.vue b/components/Posts/PostLink.vue index 7b2c527..54cd934 100644 --- a/components/ChroniclePost.vue +++ b/components/Posts/PostLink.vue @@ -1,15 +1,17 @@ <template> - <a :href="route" class="post"> - <div> - <h4 class="post-title">{{title}}</h4> - <p class="post-description">{{shortenedDescription}}...</p> - </div> - </a> + <div class="post-link"> + <a :href="route"> + <div class="post-container"> + <h4 class="post-title">{{ title }}</h4> + <p class="post-description">{{ shortenedDescription }}...</p> + </div> + </a> + </div> </template> <script> export default { - name: 'ChroniclePost', + name: 'PostLink', props: { title: { type: String, @@ -34,27 +36,39 @@ export default { </script> <style scoped> -.post { +.post-link { margin: 20px; flex-basis: 410px; + max-width: 410px; + /* height: 250px; */ + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); + background: #ffffff; + text-align: left; + transition: transform 300ms ease-in-out; +} + +.post-link:hover { + box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); + transform: scale(1.02); +} + +.post-link > a { text-decoration: none; + height: 100%; } -.post > div { - background: #ffffff; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); +.post-link .post-container { padding: 20px; - - text-align: left; + height: 100%; } -.post-title { +.post-link .post-title { color: #181818; font-size: 1.3em; } -.post-description { +.post-link .post-description { color: #484848; font-size: 0.9em; } -</style> \ No newline at end of file +</style> diff --git a/components/Posts/PostList/PostList.vue b/components/Posts/PostList/PostList.vue new file mode 100644 index 0000000..80369a8 --- /dev/null +++ b/components/Posts/PostList/PostList.vue @@ -0,0 +1,34 @@ +<template> + <pure-post-list v-if="posts" :posts="parsedPosts" :loading="loading" /> +</template> + +<script> +import PurePostList from './PurePostList' + +export default { + name: 'PostList', + components: { PurePostList }, + props: { + max: { + type: Number, + required: false, + default: () => 4 + }, + posts: { + type: Array, + required: false + } + }, + computed: { + parsedPosts() { + if (this.max) { + return this.posts.slice(0, this.max) + } + return this.posts + }, + loading() { + return this.posts === undefined + } + } +} +</script> diff --git a/components/Posts/PostList/PurePostList.stories.js b/components/Posts/PostList/PurePostList.stories.js new file mode 100644 index 0000000..e2c39de --- /dev/null +++ b/components/Posts/PostList/PurePostList.stories.js @@ -0,0 +1,30 @@ +import { storiesOf } from '@storybook/vue' + +import { postLink } from '../PostLink.stories' + +import PurePostList from './PurePostList' + +export const posts = Array(5).fill(postLink) + +storiesOf('Posts/PurePostList', module) + .add('default', () => { + return { + components: { PurePostList }, + template: `<pure-post-list :posts="posts"/>`, + data: () => ({ posts }) + } + }) + .add('loading', () => { + return { + components: { PurePostList }, + template: `<pure-post-list :posts="posts" loading/>`, + data: () => ({ posts: [] }) + } + }) + .add('no posts', () => { + return { + components: { PurePostList }, + template: `<pure-post-list :posts="posts"/>`, + data: () => ({ posts: [] }) + } + }) diff --git a/components/Posts/PostList/PurePostList.vue b/components/Posts/PostList/PurePostList.vue new file mode 100644 index 0000000..ace069f --- /dev/null +++ b/components/Posts/PostList/PurePostList.vue @@ -0,0 +1,91 @@ +<template> + <div class="post-list"> + <div v-if="loading" class="post-list-container"> + <div class="loading-post" v-for="(_, index) in 4" :key="index"></div> + </div> + <div v-else-if="!posts" class="no-posts">Brak wpisów</div> + <transition name="fade-in"> + <div v-if="posts && !loading" class="post-list-container"> + <post-link + v-for="(post, index) in posts" + :key="index" + :route="post.route" + :title="post.title" + :description="post.description" + /> + </div> + </transition> + </div> +</template> + +<script> +import PostLink from '../PostLink' + +export default { + name: 'PurePostList', + components: { PostLink }, + props: { + posts: { + type: Array, + required: true + }, + loading: { + type: Boolean, + required: false, + default: () => false + } + } +} +</script> + +<style scoped> +.post-list { + width: 100%; + max-width: 900px; + justify-content: center; + margin: 0 auto; +} + +.post-list-container { + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +@keyframes loading { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} + +.loading-post { + background: #efefef; + animation: loading 1.5s ease-in-out infinite; + margin: 20px; + flex-basis: 410px; + width: 410px; + height: 250px; + text-align: left; +} + +.no-posts { + text-align: center; +} + +@keyframes fade-in { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +.fade-in-enter-active { + animation: fade-in 0.3s reverse; +} +</style> diff --git a/components/Posts/PostList/README.md b/components/Posts/PostList/README.md new file mode 100644 index 0000000..839f9c2 --- /dev/null +++ b/components/Posts/PostList/README.md @@ -0,0 +1,42 @@ +## PostList + +This component creates a list of posts + +### Usage + +```html +<template> + <post-list :posts="posts"> +</template> + +<script> +import PostList, { getPosts } from '~/components/Posts/PostList'; + +export default { + components: { PostList }, + async asyncData() { + return { + posts: await getPosts() + } + } +} +</script> +``` + +Or by using the mixin + +```html +<template> + <post-list :posts="posts"> +</template> + +<script> +import PostList from '~/components/Posts/PostList'; +import postListParentMixin from '~/components/Posts/PostList/parentMixin'; + +export default { + components: { PostList }, + mixins: [postListParentMixin] +} +</script> +``` diff --git a/components/Posts/PostList/index.js b/components/Posts/PostList/index.js new file mode 100644 index 0000000..11d44ff --- /dev/null +++ b/components/Posts/PostList/index.js @@ -0,0 +1,22 @@ +import axios from 'axios' + +import k from '~/api' +import PostList from './PostList' + +export const getPosts = async () => { + if (process.client) { + let posts = await axios.get(`${window.location.origin}/api/posts.json`) + return parsePosts(posts.data) + } else { + return parsePosts(k.getPosts()) + } +} + +export const parsePosts = posts => + posts.map(post => ({ + title: post.content.meta.title, + description: post.content.description, + route: post.route + })) + +export default PostList diff --git a/components/Posts/PostList/parentMixin.js b/components/Posts/PostList/parentMixin.js new file mode 100644 index 0000000..e5b06ed --- /dev/null +++ b/components/Posts/PostList/parentMixin.js @@ -0,0 +1,9 @@ +import { getPosts } from './index' + +export default { + async asyncData() { + return { + posts: await getPosts() + } + } +} diff --git a/components/Ranking/RankingEntry.stories.js b/components/Ranking/RankingEntry.stories.js new file mode 100644 index 0000000..20bf6e1 --- /dev/null +++ b/components/Ranking/RankingEntry.stories.js @@ -0,0 +1,19 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../../.storybook/decorators' + +import RankingEntry from './RankingEntry' + +export const rankingEntry = { + troop: 'Test', + points: 32 +} + +storiesOf('Ranking/RankingEntry', module) + .addDecorator(center) + .add('default', () => { + return { + components: { RankingEntry }, + template: `<ranking-entry :troop="troop" :points="points" />`, + data: () => rankingEntry + } + }) diff --git a/components/Ranking/RankingFirstEntry.stories.js b/components/Ranking/RankingFirstEntry.stories.js new file mode 100644 index 0000000..05fa517 --- /dev/null +++ b/components/Ranking/RankingFirstEntry.stories.js @@ -0,0 +1,16 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../../.storybook/decorators' + +import RankingFirstEntry from './RankingFirstEntry' + +import { rankingEntry } from './RankingEntry.stories' + +storiesOf('Ranking/RankingFirstEntry', module) + .addDecorator(center) + .add('default', () => { + return { + components: { RankingFirstEntry }, + template: `<ranking-first-entry :troop="troop" :points="points" />`, + data: () => rankingEntry + } + }) diff --git a/components/Ranking/RankingFirstEntry.vue b/components/Ranking/RankingFirstEntry.vue index d9f290b..ad0bea0 100644 --- a/components/Ranking/RankingFirstEntry.vue +++ b/components/Ranking/RankingFirstEntry.vue @@ -44,6 +44,7 @@ export default { .ranking-first-entry__troop { grid-column: 2; + text-align: center; } .ranking-first-entry__points { diff --git a/components/Ranking/RankingList.stories.js b/components/Ranking/RankingList.stories.js new file mode 100644 index 0000000..ad3576b --- /dev/null +++ b/components/Ranking/RankingList.stories.js @@ -0,0 +1,23 @@ +import { storiesOf } from '@storybook/vue' +import { center } from '../../.storybook/decorators' + +import RankingList from './RankingList' + +import { rankingEntry } from './RankingEntry.stories' + +const rankingList = { + scores: Array.from(Array(3).keys()).map(i => ({ + ...rankingEntry, + troop: `Troop${i}` + })) +} + +storiesOf('Ranking/RankingList', module) + .addDecorator(center) + .add('default', () => { + return { + components: { RankingList }, + template: `<ranking-list :scores="scores" />`, + data: () => rankingList + } + }) diff --git a/components/TheFooter.stories.js b/components/TheFooter.stories.js new file mode 100644 index 0000000..ceb5015 --- /dev/null +++ b/components/TheFooter.stories.js @@ -0,0 +1,29 @@ +import { storiesOf } from '@storybook/vue' +import { action } from '@storybook/addon-actions' + +import TheFooter from './TheFooter' + +export const routes = [ + { path: '/', name: 'Strona główna' }, + { path: '/download', name: 'Do pobrania' }, + { path: '/kontakt', name: 'Kontakt' }, + { path: '/kronika', name: 'Kronika' } +] + +const footer = { + routes +} + +const alwaysBottom = () => ({ + template: `<div style="display:flex;flex-direction:column;min-height:100vh"><div style="flex:1"></div><story/></div>` +}) + +storiesOf('TheFooter', module) + .addDecorator(alwaysBottom) + .add('default', () => { + return { + components: { TheFooter }, + template: `<the-footer :routes="routes" />`, + data: () => footer + } + }) diff --git a/components/Footer.vue b/components/TheFooter.vue index 69ea76a..e19c86a 100644 --- a/components/Footer.vue +++ b/components/TheFooter.vue @@ -25,6 +25,7 @@ <script> export default { + name: 'TheFooter', props: { routes: Array, specialRoutes: Array, diff --git a/components/TheHeader.stories.js b/components/TheHeader.stories.js new file mode 100644 index 0000000..ee320b7 --- /dev/null +++ b/components/TheHeader.stories.js @@ -0,0 +1,24 @@ +import { storiesOf } from '@storybook/vue' +import { routes } from './TheFooter.stories' + +import TheHeader from './TheHeader' + +const header = { + routes, + title: '19 PDH Puszcza', + logo: '/assets/krajka-logo.svg' +} + +const alwaysTop = () => ({ + template: `<div style="display:flex;flex-direction:column;min-height:100vh"><story/><div style="flex:1"></div></div>` +}) + +storiesOf('TheHeader', module) + .addDecorator(alwaysTop) + .add('default', () => { + return { + components: { TheHeader }, + template: `<the-header :routes="routes" :title="title" :logo="logo"/>`, + data: () => header + } + }) diff --git a/components/NavBar.vue b/components/TheHeader.vue index 4bbae72..4d17616 100644 --- a/components/NavBar.vue +++ b/components/TheHeader.vue @@ -1,27 +1,20 @@ <template> - <nav :class="navbarClass"> + <nav class="navbar" :class="{ 'menu-open': showMenu }"> <div class="title"> <img v-if="logo" class="logo" :src="logo" alt="ZHR" /> - <nuxt-link :class="titleClass" to="/">{{ title }}</nuxt-link> + <nuxt-link class="title-name" :class="{ margin: logo }" to="/">{{ + title + }}</nuxt-link> </div> <div class="space"></div> <button @click="toggleMenu" class="menu-toggler">Menu</button> - <ul :class="linksClass" @click="toggleMenu"> + <ul class="links" :class="{ show: this.showMenu }" @click="toggleMenu"> <!-- Loop for generating links --> - <NavLink v-for="route in routes" :key="route.path" :link="route.path" :name="route.name" /> - <NavLink - v-for="route in staticRoutes" + <nav-link + v-for="route in routes" :key="route.path" :link="route.path" :name="route.name" - pure - /> - <NavLink - v-for="route in externalRoutes" - :key="route.path" - :link="route.path" - :name="route.name" - external /> </ul> </nav> @@ -31,47 +24,33 @@ import NavLink from './NavLink' export default { + name: 'TheHeader', components: { NavLink }, props: { - routes: Array, - externalRoutes: Array, - staticRoutes: Array, - title: String, - logo: String - }, - computed: { - titleClass() { - if (this.logo) { - return 'title-name margin' - } - return 'title-name' + routes: { + type: Array, + required: true }, - navbarClass() { - if (this.menuCollapsed) { - return 'navbar' - } - return 'navbar menu-open' + title: { + type: String, + required: true }, - linksClass() { - if (this.menuCollapsed) { - return 'links' - } - return 'links show' + logo: { + type: String, + required: false, + default: () => '' } }, data: function() { return { - menuCollapsed: true + showMenu: false } }, methods: { toggleMenu() { - this.menuCollapsed = !this.menuCollapsed - }, - linksClick() { - this.toggleMenu() + this.showMenu = !this.showMenu } } } @@ -208,4 +187,4 @@ export default { height: calc(100% - 80px); } } -</style> \ No newline at end of file +</style> |