Merge pull request #1906 from Human-Connection/add_storybook_stories_for_our_university_students

Add storybook stories for our university students
This commit is contained in:
mattwr18 2019-10-22 11:58:17 +02:00 committed by GitHub
commit 98e3bb40d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 264 additions and 129 deletions

View File

@ -0,0 +1,45 @@
import { storiesOf } from '@storybook/vue'
import { withA11y } from '@storybook/addon-a11y'
import HcCommentList from './CommentList.vue'
import helpers from '~/storybook/helpers'
import faker from 'faker'
helpers.init()
const commentMock = fields => {
return {
id: faker.random.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraph(),
createdAt: faker.date.past(),
updatedAt: faker.date.recent(),
deleted: false,
disabled: false,
...fields,
}
}
const comments = [
commentMock(),
commentMock(),
commentMock(),
commentMock(),
commentMock(),
commentMock(),
commentMock(),
commentMock(),
commentMock(),
commentMock(),
]
storiesOf('CommentList', module)
.addDecorator(withA11y)
.addDecorator(helpers.layout)
.add('given 10 comments', () => ({
components: { HcCommentList },
store: helpers.store,
data: () => ({
post: { comments },
}),
template: `<hc-comment-list :post="post" />`,
}))

View File

@ -0,0 +1,75 @@
import { storiesOf } from '@storybook/vue'
import { withA11y } from '@storybook/addon-a11y'
import { action } from '@storybook/addon-actions'
import Vuex from 'vuex'
import helpers from '~/storybook/helpers'
import LoginForm from './LoginForm.vue'
helpers.init()
const createStore = ({ loginSuccess }) => {
return new Vuex.Store({
modules: {
auth: {
namespaced: true,
state: () => ({
pending: false,
}),
mutations: {
SET_PENDING(state, pending) {
state.pending = pending
},
},
getters: {
pending(state) {
return !!state.pending
},
},
actions: {
async login({ commit, dispatch }, args) {
action('Vuex action `auth/login`')(args)
return new Promise((resolve, reject) => {
commit('SET_PENDING', true)
setTimeout(() => {
commit('SET_PENDING', false)
if (loginSuccess) {
resolve(loginSuccess)
} else {
reject(new Error('Login unsuccessful'))
}
}, 1000)
})
},
},
},
},
})
}
storiesOf('LoginForm', module)
.addDecorator(withA11y)
.addDecorator(helpers.layout)
.add('successful login', () => {
return {
components: { LoginForm },
store: createStore({ loginSuccess: true }),
methods: {
handleSuccess() {
action('Login successful!')()
},
},
template: `<login-form @success="handleSuccess"/>`,
}
})
.add('unsuccessful login', () => {
return {
components: { LoginForm },
store: createStore({ loginSuccess: false }),
methods: {
handleSuccess() {
action('Login successful!')()
},
},
template: `<login-form @success="handleSuccess"/>`,
}
})

View File

@ -0,0 +1,121 @@
<template>
<ds-container width="medium">
<ds-space margin="small">
<blockquote>
<p>{{ $t('quotes.african.quote') }}</p>
<b>- {{ $t('quotes.african.author') }}</b>
</blockquote>
</ds-space>
<ds-card class="login-card">
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', sm: '50%' }" centered>
<client-only>
<locale-switch class="login-locale-switch" offset="5" />
</client-only>
<ds-space margin-top="small" margin-bottom="xxx-small" centered>
<img
class="login-image"
alt="Human Connection"
src="/img/sign-up/humanconnection.svg"
/>
</ds-space>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: '50%' }" centered>
<ds-space margin="small">
<a :href="$t('login.moreInfoURL')" :title="$t('login.moreInfoHint')" target="_blank">
{{ $t('login.moreInfo') }}
</a>
</ds-space>
<ds-space margin="small">
<ds-text size="small">{{ $t('login.copy') }}</ds-text>
</ds-space>
<form :disabled="pending" @submit.prevent="onSubmit">
<ds-input
v-model="form.email"
:disabled="pending"
:placeholder="$t('login.email')"
type="email"
name="email"
icon="envelope"
/>
<ds-input
v-model="form.password"
:disabled="pending"
:placeholder="$t('login.password')"
icon="lock"
icon-right="question-circle"
name="password"
type="password"
/>
<ds-space margin-bottom="large">
<nuxt-link to="/password-reset/request">{{ $t('login.forgotPassword') }}</nuxt-link>
</ds-space>
<ds-button
:loading="pending"
primary
fullwidth
name="submit"
type="submit"
icon="sign-in"
>
{{ $t('login.login') }}
</ds-button>
<ds-space margin-top="large" margin-bottom="x-small">
{{ $t('login.no-account') }}
<nuxt-link to="/registration/signup">{{ $t('login.register') }}</nuxt-link>
</ds-space>
</form>
</ds-flex-item>
</ds-flex>
</ds-card>
</ds-container>
</template>
<script>
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch.vue'
export default {
components: {
LocaleSwitch,
},
data() {
return {
form: {
email: '',
password: '',
},
}
},
computed: {
pending() {
return this.$store.getters['auth/pending']
},
},
methods: {
async onSubmit() {
try {
await this.$store.dispatch('auth/login', { ...this.form })
this.$toast.success(this.$t('login.success'))
this.$emit('success')
} catch (err) {
this.$toast.error(this.$t('login.failure'))
}
},
},
}
</script>
<style lang="scss">
.login-image {
width: 90%;
max-width: 200px;
}
.login-card {
position: relative;
}
.login-locale-switch {
position: absolute;
top: 1em;
left: 1em;
}
</style>

View File

@ -112,7 +112,8 @@
"moreInfoURL": "https://human-connection.org",
"moreInfoHint": "zur Präsentationsseite",
"hello": "Hallo",
"success": "Du bist eingeloggt!"
"success": "Du bist eingeloggt!",
"failure": "Fehlerhafte E-Mail-Adresse oder Passwort."
},
"editor": {
"placeholder": "Schreib etwas Inspirierendes …",

View File

@ -113,7 +113,8 @@
"moreInfoURL": "https://human-connection.org/en/",
"moreInfoHint": "to the presentation page",
"hello": "Hello",
"success": "You are logged in!"
"success": "You are logged in!",
"failure": "Incorrect email address or password."
},
"editor": {
"placeholder": "Leave your inspirational thoughts …",

View File

@ -12,7 +12,7 @@
"scripts": {
"dev": "nuxt",
"dev:styleguide": "cross-env STYLEGUIDE_DEV=true yarn run dev",
"storybook": "start-storybook -p 3002 -c storybook/",
"storybook": "start-storybook -p 3002 -s ./static -c storybook/",
"build": "nuxt build",
"start": "nuxt start",
"generate:maintenance": "nuxt generate -c nuxt.config.maintenance.js",
@ -121,6 +121,7 @@
"eslint-plugin-promise": "~4.2.1",
"eslint-plugin-standard": "~4.0.1",
"eslint-plugin-vue": "~5.2.3",
"faker": "^4.1.0",
"flush-promises": "^1.0.2",
"fuse.js": "^3.4.5",
"identity-obj-proxy": "^3.0.0",

View File

@ -1,138 +1,27 @@
<template>
<transition name="fade" appear>
<ds-container v-if="ready" width="medium">
<ds-space margin="small">
<blockquote>
<p>{{ $t('quotes.african.quote') }}</p>
<b>- {{ $t('quotes.african.author') }}</b>
</blockquote>
</ds-space>
<ds-card class="login-card">
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', sm: '50%' }" centered>
<client-only>
<locale-switch class="login-locale-switch" offset="5" />
</client-only>
<ds-space margin-top="small" margin-bottom="xxx-small" centered>
<img
class="login-image"
alt="Human Connection"
src="/img/sign-up/humanconnection.svg"
/>
</ds-space>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: '50%' }" centered>
<ds-space margin="small">
<a :href="$t('login.moreInfoURL')" :title="$t('login.moreInfoHint')" target="_blank">
{{ $t('login.moreInfo') }}
</a>
</ds-space>
<ds-space margin="small">
<ds-text size="small">{{ $t('login.copy') }}</ds-text>
</ds-space>
<form :disabled="pending" @submit.prevent="onSubmit">
<ds-input
v-model="form.email"
:disabled="pending"
:placeholder="$t('login.email')"
type="email"
name="email"
icon="envelope"
/>
<ds-input
v-model="form.password"
:disabled="pending"
:placeholder="$t('login.password')"
icon="lock"
icon-right="question-circle"
name="password"
type="password"
/>
<ds-space margin-bottom="large">
<nuxt-link to="/password-reset/request">{{ $t('login.forgotPassword') }}</nuxt-link>
</ds-space>
<ds-button
:loading="pending"
primary
fullwidth
name="submit"
type="submit"
icon="sign-in"
>
{{ $t('login.login') }}
</ds-button>
<ds-space margin-top="large" margin-bottom="x-small">
{{ $t('login.no-account') }}
<nuxt-link to="/registration/signup">{{ $t('login.register') }}</nuxt-link>
</ds-space>
</form>
</ds-flex-item>
</ds-flex>
</ds-card>
</ds-container>
<login-form @success="handleSuccess" />
</transition>
</template>
<script>
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import LoginForm from '~/components/LoginForm/LoginForm.vue'
import { VERSION } from '~/constants/terms-and-conditions-version.js'
export default {
layout: 'no-header',
components: {
LocaleSwitch,
},
data() {
return {
ready: false,
form: {
email: '',
password: '',
},
}
},
computed: {
pending() {
return this.$store.getters['auth/pending']
},
LoginForm,
},
asyncData({ store, redirect }) {
if (store.getters['auth/user'].termsAndConditionsAgreedVersion === VERSION) {
redirect('/')
}
},
mounted() {
setTimeout(() => {
// NOTE: quick fix for jumping flexbox implementation
// will be fixed in a future update of the styleguide
this.ready = true
}, 50)
},
methods: {
async onSubmit() {
try {
await this.$store.dispatch('auth/login', { ...this.form })
this.$toast.success(this.$t('login.success'))
this.$router.replace(this.$route.query.path || '/')
} catch (err) {
this.$toast.error(err.message)
}
handleSuccess() {
this.$router.replace(this.$route.query.path || '/')
},
},
}
</script>
<style lang="scss">
.login-image {
width: 90%;
max-width: 200px;
}
.login-card {
position: relative;
}
.login-locale-switch {
position: absolute;
top: 1em;
left: 1em;
}
</style>

View File

@ -3,7 +3,9 @@ import Vuex from 'vuex'
import vuexI18n from 'vuex-i18n/dist/vuex-i18n.umd.js'
import Styleguide from '@human-connection/styleguide'
import Filters from '~/plugins/vue-filters'
import IziToast from '~/plugins/izi-toast'
import layout from './layout.vue'
import locales from '~/locales/index.js'
import '~/plugins/v-tooltip'
@ -12,10 +14,13 @@ const helpers = {
Vue.use(Vuex)
Vue.use(Styleguide)
Vue.use(Filters)
Vue.use(IziToast)
Vue.use(vuexI18n.plugin, helpers.store)
Vue.i18n.add('en', require('~/locales/en.json'))
Vue.i18n.add('de', require('~/locales/de.json'))
locales.forEach(({ code }) => {
Vue.i18n.add(code, require(`~/locales/${code}.json`))
})
Vue.i18n.set('en')
Vue.i18n.fallback('en')
@ -35,14 +40,6 @@ const helpers = {
},
},
},
editor: {
namespaced: true,
getters: {
placeholder(state) {
return 'Leave your inspirational thoughts ...'
},
},
},
},
}),
layout(storyFn) {

View File

@ -7359,6 +7359,11 @@ extsprintf@^1.2.0:
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
faker@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f"
integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=
fast-deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"