hc experiment progress

This commit is contained in:
Grzegorz Leoniec 2018-10-09 14:11:21 +02:00
commit 4dbe142dcb
30 changed files with 9097 additions and 0 deletions

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

4
.eslintignore Normal file
View File

@ -0,0 +1,4 @@
node_modules
build
.nuxt
cypress/

24
.eslintrc.js Normal file
View File

@ -0,0 +1,24 @@
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
parser: 'babel-eslint'
},
extends: [
'plugin:vue/recommended',
'plugin:prettier/recommended'
],
// required to lint *.vue files
plugins: [
'vue',
'prettier'
],
// add your custom rules here
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}

81
.gitignore vendored Normal file
View File

@ -0,0 +1,81 @@
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# Nuxt generate
dist
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# IDE
.idea

6
.prettierrc Normal file
View File

@ -0,0 +1,6 @@
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"bracketSpacing": true
}

21
README.md Normal file
View File

@ -0,0 +1,21 @@
# graphql-ui
> Human Connection GraphQL UI Prototype
## Build Setup
``` bash
# install dependencies
$ yarn install
# serve with hot reload at localhost:3000
$ yarn run dev
# build for production and launch server
$ yarn run build
$ yarn start
```
## Styleguide
All reusable Components (for example avatar) should be done inside the

7
assets/README.md Normal file
View File

@ -0,0 +1,7 @@
# ASSETS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).

79
components/Logo.vue Normal file
View File

@ -0,0 +1,79 @@
<template>
<div class="VueToNuxtLogo">
<div class="Triangle Triangle--two"/>
<div class="Triangle Triangle--one"/>
<div class="Triangle Triangle--three"/>
<div class="Triangle Triangle--four"/>
</div>
</template>
<style>
.VueToNuxtLogo {
display: inline-block;
animation: turn 2s linear forwards 1s;
transform: rotateX(180deg);
position: relative;
overflow: hidden;
height: 180px;
width: 245px;
}
.Triangle {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}
.Triangle--one {
border-left: 105px solid transparent;
border-right: 105px solid transparent;
border-bottom: 180px solid #41b883;
}
.Triangle--two {
top: 30px;
left: 35px;
animation: goright 0.5s linear forwards 3.5s;
border-left: 87.5px solid transparent;
border-right: 87.5px solid transparent;
border-bottom: 150px solid #3b8070;
}
.Triangle--three {
top: 60px;
left: 35px;
animation: goright 0.5s linear forwards 3.5s;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 120px solid #35495e;
}
.Triangle--four {
top: 120px;
left: 70px;
animation: godown 0.5s linear forwards 3s;
border-left: 35px solid transparent;
border-right: 35px solid transparent;
border-bottom: 60px solid #fff;
}
@keyframes turn {
100% {
transform: rotateX(0deg);
}
}
@keyframes godown {
100% {
top: 180px;
}
}
@keyframes goright {
100% {
left: 70px;
}
}
</style>

7
components/README.md Normal file
View File

@ -0,0 +1,7 @@
# COMPONENTS
**This directory is not required, you can delete it if you don't want to use it.**
The components directory contains your Vue.js Components.
_Nuxt.js doesn't supercharge these components._

7
layouts/README.md Normal file
View File

@ -0,0 +1,7 @@
# LAYOUTS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Application Layouts.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).

61
layouts/default.vue Normal file
View File

@ -0,0 +1,61 @@
<template>
<div>
<div class="main-navigation">
<ds-container style="padding: .5rem 3rem .2rem;">
<a
v-router-link
href="/">
<ds-logo />
</a>
</ds-container>
</div>
<ds-container>
<div style="padding: 5rem 2rem;">
<nuxt/>
</div>
</ds-container>
</div>
</template>
<style lang="scss">
@import 'vue-cion-design-system/src/system/tokens/generated/tokens.scss';
// Transition Easing
$easeOut: cubic-bezier(0.19, 1, 0.22, 1);
.layout-enter-active {
transition: opacity 80ms ease-out;
transition-delay: 80ms;
}
.layout-leave-active {
transition: opacity 80ms ease-in;
}
.layout-enter,
.layout-leave-active {
opacity: 0;
}
// slide up ease
.slide-up-enter-active {
transition: all 500ms $easeOut;
transition-delay: 20ms;
opacity: 1;
transform: translate3d(0, 0, 0);
}
.slide-up-enter,
.slide-up-leave-active {
opacity: 0;
box-shadow: none;
transform: translate3d(0, 15px, 0);
}
.main-navigation {
background: #fff;
}
.tags {
.ds-tag {
margin-right: $space-xx-small;
}
}
</style>

8
middleware/README.md Normal file
View File

@ -0,0 +1,8 @@
# MIDDLEWARE
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your application middleware.
The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts).
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).

148
nuxt.config.js Normal file
View File

@ -0,0 +1,148 @@
const pkg = require('./package')
module.exports = {
mode: 'universal',
transition: {
name: 'slide-up',
mode: 'out-in'
},
/*
** Headers of the page
*/
head: {
title: 'Human Connection',
titleTemplate: '%s - Human Connection',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
/*
** Customize the progress-bar color
*/
loading: {
color: '#86b31e',
height: '2px',
duration: 20000
},
/*
** Global CSS
*/
css: [],
/*
** Plugins to load before mounting the App
*/
plugins: [
{ src: '~/plugins/design-system.js', ssr: true },
{ src: '~/plugins/vue-directives.js', ssr: false }
],
router: {
// middleware: [
// 'maintenance',
// 'check-auth',
// 'authenticated'
// ],
linkActiveClass: 'router-active-link'
},
/* router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'post-slug',
path: '/post/:slug',
component: 'pages/post/_slug.vue',
children: [
{
path: 'more-info',
component: 'pages/post/_slug.vue'
},
{
path: 'take-action',
component: 'pages/post/_slug.vue'
}
]
}
]
}, */
/*
** Nuxt.js modules
*/
modules: ['@nuxtjs/apollo'],
// Give apollo module options
apollo: {
tokenName: 'yourApolloTokenName', // optional, default: apollo-token
tokenExpires: 10, // optional, default: 7 (days)
includeNodeModules: true, // optional, default: false (this includes graphql-tag for node_modules folder)
authenticationType: 'Basic', // optional, default: 'Bearer'
// optional
errorHandler(error) {
console.log(
'%cError',
'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;',
error.message
)
},
// required
clientConfigs: {
default: {
// required
httpEndpoint: 'http://localhost:4000',
// optional
// See https://www.apollographql.com/docs/link/links/http.html#options
httpLinkOptions: {
credentials: 'same-origin'
},
// You can use `wss` for secure connection (recommended in production)
// Use `null` to disable subscriptions
// wsEndpoint: 'ws://localhost:4000', // optional
// LocalStorage token
tokenName: 'apollo-token', // optional
// Enable Automatic Query persisting with Apollo Engine
persisting: false, // Optional
// Use websockets for everything (no HTTP)
// You need to pass a `wsEndpoint` for this to work
websocketsOnly: false // Optional
}
}
},
manifest: {
name: 'Human-Connection.org',
description: 'Human-Connection.org',
theme_color: '#ffffff',
lang: 'de'
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {
// Run ESLint on save
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
}
}
}

37
package.json Normal file
View File

@ -0,0 +1,37 @@
{
"name": "hc-webapp-next",
"version": "1.0.0",
"description": "Human Connection GraphQL UI Prototype",
"author": "Grzegorz Leoniec",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"styleguide": "(cd ./styleguide && yarn dev)",
"styleguide:build": "(cd ./styleguide && yarn build:lib) && yarn upgrade file:./styleguide",
"precommit": "npm run lint"
},
"dependencies": {
"@nuxtjs/apollo": "^4.0.0-rc3",
"cross-env": "^5.2.0",
"express": "^4.16.3",
"graphql-tag": "^2.10.0",
"nuxt": "^2.0.0",
"vue-cion-design-system": "file:./styleguide"
},
"devDependencies": {
"babel-eslint": "^10.0.1",
"eslint": "^5.0.1",
"eslint-config-prettier": "^3.1.0",
"eslint-loader": "^2.0.0",
"eslint-plugin-prettier": "3.0.0",
"eslint-plugin-vue": "^4.0.0",
"node-sass": "^4.9.3",
"nodemon": "^1.11.0",
"prettier": "1.14.3",
"sass-loader": "^7.1.0"
}
}

6
pages/README.md Normal file
View File

@ -0,0 +1,6 @@
# PAGES
This directory contains your Application Views and Routes.
The framework reads all the `*.vue` files inside this directory and create the router of your application.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).

115
pages/index.vue Normal file
View File

@ -0,0 +1,115 @@
<template>
<div>
<no-ssr>
<ds-flex
:width="{ base: '100%' }"
gutter="base">
<ds-flex-item
v-for="post in Post"
:width="{ base: '100%', xs: '100%', md: '50%', xl: '33%' }"
:key="post.id">
<a
v-router-link
:href="href(post)"
>
<ds-card
:header="post.title"
:image="post.image"
style="cursor: pointer">
<ds-avatar
:image="post.author.User.avatar"
size="32px" /> <b class="username">{{ post.author.User.name }}</b>
<ds-space />
<div v-html="post.contentExcerpt" />
<template slot="footer">
<span>
<ds-icon name="comments" /> <small v-if="post.commentsCount">{{ post.commentsCount }}</small>
</span>
&nbsp;
<span>
<ds-icon name="heart-o" /> <small v-if="post.shoutedCount">{{ post.shoutedCount }}</small>
</span>
</template>
</ds-card>
</a>
</ds-flex-item>
</ds-flex>
</no-ssr>
</div>
</template>
<script>
import gql from 'graphql-tag'
export default {
data() {
return {
// Initialize your apollo data
Post: []
}
},
computed: {
tags() {
return this.Post ? this.Post[0].tags.map(tag => tag.name) : '-'
}
},
methods: {
href(post) {
return this.$router.resolve({
name: 'post-slug',
params: { slug: post.slug }
}).href
}
},
apollo: {
Post: {
query: gql(`
query {
Post {
id
title
contentExcerpt
slug
image
author {
User {
avatar
slug
name
}
}
tags {
name
}
commentsCount
comments(orderBy: _id_desc) {
id
content
author {
User {
name
}
}
}
categories {
name
}
shoutedCount
shoutedBy {
name
friends {
name
}
}
}
}
`),
variables() {
return {
id: this.$route.query.post || 'p1'
}
}
}
}
}
</script>

56
pages/post/_slug.vue Normal file
View File

@ -0,0 +1,56 @@
<template>
<div>
<no-ssr>
<ds-flex gutter="small">
<ds-flex-item>
<transition
name="slide-up"
appear>
<nuxt-child />
</transition>
</ds-flex-item>
<ds-flex-item :width="{ base: '200px' }">
<ds-menu
:routes="routes" />
</ds-flex-item>
</ds-flex>
</no-ssr>
</div>
</template>
<script>
export default {
data() {
return {
routes: [
{
name: 'Post',
path: `/post/${this.$route.params.slug}`,
children: [
{
name: 'Kommentare',
path: `/post/${this.$route.params.slug}#comments`
},
{
name: 'Miteinandere reden',
path: `/post/${this.$route.params.slug}#lets-talk`
},
{
name: 'Versus',
path: `/post/${this.$route.params.slug}#versus`
}
]
},
{
name: 'Mehr Info',
path: `/post/${this.$route.params.slug}/more-info`
},
{
name: 'Aktiv werden',
path: `/post/${this.$route.params.slug}/take-action`
}
]
}
}
}
</script>

189
pages/post/_slug/index.vue Normal file
View File

@ -0,0 +1,189 @@
<template>
<ds-card
v-if="post"
:image="post.image"
:header="post.title"
class="post-card">
<a
v-router-link
:href="$router.resolve({ name: 'profile-slug', params: { slug: post.author.User.slug } }).href">
<ds-avatar
:image="post.author.User.avatar"
size="32px" /> <b class="username">{{ post.author.User.name }}</b>
</a>
<ds-space margin-bottom="small" />
<div
class="content"
v-html="post.content" />
<ds-space margin-top="large"/>
<div class="tags">
<ds-icon name="compass" /> <ds-tag
v-for="category in post.categories"
:key="category.id">{{ category.name }}</ds-tag>
</div>
<template v-if="post.tags && post.tags.length">
<div class="tags">
<ds-icon name="tags" /> <ds-tag
v-for="tag in post.tags"
:key="tag.id"><ds-icon name="tag" /> {{ tag.name }}</ds-tag>
</div>
</template>
<ds-space margin-bottom="large" />
<ds-section
slot="footer">
<h3 style="margin-top: 0;">
<span>
<ds-icon name="comments" />
<ds-tag
v-if="post.commentsCount"
style="transform: scale(.8); margin-top: -4px; margin-left: -12px; position: absolute;"
color="primary"
round>
{{ post.commentsCount }}
</ds-tag> &nbsp; Comments
</span>
</h3>
<ds-space margin-bottom="large" />
<div
v-if="post.commentsCount"
id="comments"
class="comments">
<div
v-for="comment in post.comments"
:key="comment.id"
class="comment">
<ds-space margin-bottom="x-small">
<a
v-router-link
:href="$router.resolve({ name: 'profile-slug', params: { slug: comment.author.User.slug } }).href">
<ds-avatar
:image="comment.author.User.avatar"
size="24px" /> <b class="username">{{ comment.author.User.name }}</b>
</a>
</ds-space>
<div
style="padding-left: 32px;"
v-html="comment.content" />
</div>
<ds-space margin-bottom="small" />
</div>
<div v-else>
<p style="text-align: center; opacity: .5;">NO COMMENTS</p>
</div>
</ds-section>
</ds-card>
</template>
<script>
import gql from 'graphql-tag'
export default {
transition: {
name: 'slide-up',
mode: 'out-in'
},
data() {
return {
post: null
}
},
watch: {
Post(post) {
this.post = post[0]
}
},
apollo: {
Post: {
query: gql(`
query Post($slug: String!) {
Post(slug: $slug) {
id
title
content
slug
image
author {
User {
slug
name
avatar
}
}
tags {
name
}
commentsCount
comments(orderBy: _id_desc) {
id
content
author {
User {
slug
name
avatar
}
}
}
categories {
name
}
shoutedBy {
name
friends {
name
}
}
}
}
`),
variables() {
return {
slug: this.$route.params.slug
}
}
}
}
}
</script>
<style lang="scss">
@import 'vue-cion-design-system/src/system/tokens/generated/tokens.scss';
.post-card {
// max-width: 800px;
margin: auto;
.content {
br {
display: none;
}
}
.comments {
margin-top: $space-small;
.comment {
margin-top: $space-small;
position: relative;
}
}
.ds-card-image {
img {
max-height: 300px;
object-fit: cover;
object-position: center;
}
}
.ds-card-footer {
padding: 0;
border-radius: 0 0 $border-radius-large $border-radius-large;
overflow: hidden;
.ds-section {
padding: $space-base;
}
}
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<ds-card>
<h2 style="margin-bottom: .2em;">Mehr Informationen</h2>
<p>Hier findest du weitere infos zum Thema.</p>
<ds-space/>
<h3><ds-icon name="compass" /> Themenkategorien</h3>
<div class="tags">
<ds-tag
v-for="category in post.categories"
:key="category.id">{{ category.name }}</ds-tag>
</div>
<template v-if="post.tags && post.tags.length">
<h3><ds-icon name="tags" /> Schlagwörter</h3>
<div class="tags">
<ds-tag
v-for="tag in post.tags"
:key="tag.id"><ds-icon name="tag" /> {{ tag.name }}</ds-tag>
</div>
</template>
<h3>Verwandte Beiträge</h3>
<ds-section style="margin: 0 -1.5rem; padding: 1.5rem;">
<ds-flex
v-if="post.relatedContributions && post.relatedContributions.length"
gutter="small">
<ds-flex-item
v-for="relatedPost in post.relatedContributions"
:key="relatedPost.id"
:width="{ base: '50%' }">
<a
v-router-link
:href="$router.resolve({ name: 'post-slug', params: { slug: relatedPost.slug } }).href">
<ds-card
:image="relatedPost.image"
:header="relatedPost.title"
class="related-post">
<div v-html="relatedPost.contentExcerpt" />
</ds-card>
</a>
</ds-flex-item>
</ds-flex>
<ds-space
v-else
style="text-align: center; padding-top: 2em; opacity: .6;">
No related Posts
</ds-space>
</ds-section>
<ds-space margin-bottom="large" />
</ds-card>
</template>
<script>
import gql from 'graphql-tag'
export default {
transition: {
name: 'slide-up',
mode: 'out-in'
},
computed: {
post() {
return this.Post ? this.Post[0] : {}
}
},
apollo: {
Post: {
query: gql(`
query Post($slug: String!) {
Post(slug: $slug) {
id
title
tags {
id
name
}
categories {
id
name
}
relatedContributions(first: 2) {
id
title
slug
image
contentExcerpt
shoutedCount
commentsCount
}
shoutedCount
shoutedBy {
name
friends {
name
}
}
}
}
`),
variables() {
return {
slug: this.$route.params.slug
}
}
}
}
}
</script>
<style lang="scss">
@import 'vue-cion-design-system/src/system/tokens/generated/tokens.scss';
.related-post {
box-shadow: $box-shadow-base;
.ds-card-image {
max-height: 80px;
}
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<ds-card header="Werde aktiv!">
<p>Was kann ich tun? Hier findest du mögliche Projekte, Aktioner, etc.</p>
</ds-card>
</template>
<script>
import gql from 'graphql-tag'
export default {
transition: {
name: 'slide-up',
mode: 'out-in'
},
data() {
return {
Post: []
}
},
computed: {
tags() {
return this.Post ? this.Post[0].tags.map(tag => tag.name) : '-'
}
},
apollo: {
Post: {
query: gql(`
query {
Post {
id
title
tags {
name
}
categories {
name
}
shoutedCount
shoutedBy {
name
friends {
name
}
}
}
}
`)
}
}
}
</script>

172
pages/profile/_slug.vue Normal file
View File

@ -0,0 +1,172 @@
<template>
<div>
<ds-card v-if="user && user.image">
<p>PROFILE IMAGE</p>
</ds-card>
<no-ssr>
<ds-space/>
<ds-flex
v-if="user"
:width="{ base: '100%' }"
gutter="base">
<ds-flex-item :width="{ base: '30%' }">
<ds-card style="position: relative; height: auto;">
<ds-avatar
:image="user.avatar"
class="profile-avatar"
size="120px" />
<h3 style="text-align: center;">{{ user.name }}</h3>
<ds-space/>
<ds-flex :size="{ base: '100%' }">
<ds-flex-item style="text-align: center;">
<ds-text
size="x-large"
style="margin-bottom: 0;">{{ user.followedByCount }}</ds-text>
<ds-text size="small">Fans</ds-text>
</ds-flex-item>
<ds-flex-item style="text-align: center;">
<ds-text
size="x-large"
style="margin-bottom: 0;">{{ user.friendsCount }}</ds-text>
<ds-text size="small">Freunde</ds-text>
</ds-flex-item>
</ds-flex>
<ds-space margin-bottom="small"/>
</ds-card>
<ds-space/>
<h2 style="text-align: center; margin-bottom: 10px;">Netzwerk</h2>
<ds-card style="position: relative; height: auto;">
<template v-if="user.friends.length">
<ds-space
v-for="friend in user.friends"
:key="friend.id"
margin-top="x-small"
margin-bottom="x-small">
<a
v-router-link
:href="$router.resolve({ name: 'profile-slug', params: { slug: friend.slug } }).href">
<ds-avatar
:image="friend.avatar"
size="32px" /> <b class="username">{{ friend.name }}</b>
</a>
</ds-space>
</template>
<template v-else>
<p style="text-align: center; opacity: .5;">NO FRIENDS</p>
</template>
</ds-card>
</ds-flex-item>
<ds-flex-item :width="{ base: '70%' }">
<ds-flex
:width="{ base: '100%' }"
gutter="small">
<ds-flex-item
v-for="item in user.contributions"
:width="{ base: '100%', md: '100%', xl: '50%' }"
:key="item.Post.id">
<a
v-router-link
:href="href(item.Post)"
>
<ds-card
:header="item.Post.title"
:image="item.Post.image"
style="cursor: pointer">
<div v-html="item.Post.contentExcerpt" />
<template slot="footer">
<span>
<ds-icon name="comments" /> <small v-if="item.Post.commentsCount">{{ item.Post.commentsCount }}</small>
</span>
&nbsp;
<span>
<ds-icon name="heart-o" /> <small v-if="item.Post.shoutedCount">{{ item.Post.shoutedCount }}</small>
</span>
</template>
</ds-card>
</a>
</ds-flex-item>
</ds-flex>
</ds-flex-item>
</ds-flex>
</no-ssr>
</div>
</template>
<script>
import gql from 'graphql-tag'
export default {
transition: {
name: 'slide-up',
mode: 'out-in'
},
data() {
return {
User: []
}
},
computed: {
user() {
return this.User ? this.User[0] : {}
}
},
methods: {
href(post) {
return this.$router.resolve({
name: 'post-slug',
params: { slug: post.slug }
}).href
}
},
apollo: {
User: {
query: gql(`
query User($slug: String!) {
User(slug: $slug) {
id
name
avatar
friendsCount
friends {
id
name
slug
avatar
}
badgesCount
followingCount
followedByCount
contributionsCount
contributions {
Post {
id
slug
title
contentExcerpt
shoutedCount
commentsCount
image
}
}
}
}
`),
variables() {
return {
slug: this.$route.params.slug
}
}
}
}
}
</script>
<style lang="scss">
.profile-avatar {
display: block;
margin: auto;
margin-top: -60px;
border: #fff 5px solid;
}
</style>

7
plugins/README.md Normal file
View File

@ -0,0 +1,7 @@
# PLUGINS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Javascript plugins that you want to run before mounting the root Vue.js application.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).

5
plugins/design-system.js Normal file
View File

@ -0,0 +1,5 @@
import Vue from 'vue'
import DesignSystem from 'vue-cion-design-system'
import 'vue-cion-design-system/dist/system.css'
Vue.use(DesignSystem)

33
plugins/vue-directives.js Normal file
View File

@ -0,0 +1,33 @@
import Vue from 'vue'
export default ({ app }) => {
Vue.directive('focus', {
// When the bound element is inserted into the DOM...
inserted: (el, binding) => {
// Focus the element
Vue.nextTick(() => {
if (binding.value !== false) {
el.focus()
}
})
}
})
Vue.directive('router-link', {
bind: (el, binding) => {
binding.clickEventListener = e => {
if (!e.metaKey && !e.ctrlKey) {
e.preventDefault()
app.router.push(el.getAttribute('href'))
}
}
el.addEventListener('click', binding.clickEventListener)
},
unbind: (el, binding) => {
// cleanup
if (binding.clickEventListener) {
el.removeEventListener('click', binding.clickEventListener)
}
}
})
}

34
server/index.js Normal file
View File

@ -0,0 +1,34 @@
const express = require('express')
const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const app = express()
const host = process.env.HOST || '127.0.0.1'
const port = process.env.PORT || 3000
app.set('port', port)
// Import and Set Nuxt.js options
let config = require('../nuxt.config.js')
config.dev = !(process.env.NODE_ENV === 'production')
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config)
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
// Give nuxt middleware to express
app.use(nuxt.render)
// Listen the server
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
}
start()

10
static/README.md Normal file
View File

@ -0,0 +1,10 @@
# STATIC
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your static files.
Each file inside this directory is mapped to `/`.
Example: `/static/robots.txt` is mapped as `/robots.txt`.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).

BIN
static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

10
store/README.md Normal file
View File

@ -0,0 +1,10 @@
# STORE
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Vuex Store files.
Vuex Store option is implemented in the Nuxt.js framework.
Creating a file in this directory activate the option in the framework automatically.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).

1
styleguide Submodule

@ -0,0 +1 @@
Subproject commit 83cba8953c8773515c803cac835f568bbb5f62b5

7786
yarn.lock Normal file

File diff suppressed because it is too large Load Diff