Merge pull request #138 from webgems/dev

🔀 dev into master
This commit is contained in:
wellá
2019-10-06 13:33:14 +02:00
committed by GitHub
23 changed files with 1042 additions and 118 deletions

30
.eslintrc.js Normal file
View File

@@ -0,0 +1,30 @@
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
parser: 'babel-eslint'
},
extends: [
'eslint:recommended',
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
'plugin:vue/recommended',
// 'plugin:prettier/recommended'
],
// required to lint *.vue files
plugins: [
'vue'
],
// add your custom rules here
rules: {
'semi': ['error', 'never'],
'no-console': 'off',
'vue/max-attributes-per-line': 'off',
'quotes': ['error', 'single', { 'avoidEscape': true }],
'comma-dangle': ['error', 'always-multiline'],
'vue/require-default-prop': 'off',
}
}

View File

@@ -21,7 +21,8 @@
"{",
" \"title\": \"${1:title}\",",
" \"desc\": \"${2:desc}\",",
" \"url\": \"${3:url}\"",
" \"url\": \"${3:url}\",",
" \"tags\": [\"${4:tag}\"]",
"},"
],
"description": "Add a webgem"

View File

@@ -5,4 +5,5 @@ These are lovely people who have helped this project:
* twitter: @lostdesign
- [Kevin](https://github.com/S3B4S) :dog:
- [jacobparis](https://github.com/jacobparis) : Team Devcord
* twitter: @jacobmparis
* twitter: @jacobmparis
- [JonasPardon](https://github.com/JonasPardon)

View File

@@ -39,27 +39,29 @@ For any other editor, please use the following schema:
```js
[
{
"title": "Category",
"slug": "/category",
"title": String, // Start with uppercase
"slug": String, // All lowercase, eg: "/category"
"resources": [
{
"title": "Awesome resource",
"desc": "This awesome resource will make your life much easier.", // 1 - 2 sentences long.
"url": "https://url.com"
"title": String,
"desc": String, // 1 - 2 sentences long
"url": String, // See below for notes about correct format of URLs
"tags": [String] // Please try to add at least 3 tags
}
]
}
]
```
If you just want to add a resource to an already existing category, extend the `resources` array with your resources. Please include all the keys enlisted (`title`, `desc`, `url`).
In our [resources](resources/) we have an `<category>.json` file for each category, you can add your suggested resource by adding it to the `resources` array in the JSON file using the schema as described above. Please include all the keys enlisted (`title`, `desc`, `url`, `tags`).
For URLs, please consider the following:
- Do not link to language specific pages (e.g. don't link to `<url>.org/en-US/docs`, instead, link to `<url>/docs` if possible).
- Do not use `'&'` as it will break the URL referencing.
- We won't allow referral links.
To add a completely new resource, include a new object at the root of the array, the pages are dynamically rendered so you don't have to worry about anything else. Again, include all the enlisted keys, reference to the schema above.
To add a completely new resource, add a `<category>.json` file to [resources](resources/). Make sure it follows the sceme as described above.
Add it to [resources.index.js](resources/index.js) list of imports and export it aswell, that way Nuxt can take care of rendering the page.
## Built With

View File

@@ -10,7 +10,11 @@
<script>
export default {
props: ['resource', 'isActive', 'createCopyUrl'],
props: {
resource: Object,
isActive: Boolean,
createCopyUrl: Function,
},
}
</script>
@@ -31,6 +35,12 @@ export default {
&--reference {
cursor: pointer;
display: flex;
}
&--target {
cursor: pointer;
display: flex;
}
&--links {
@@ -72,20 +82,20 @@ export default {
}
&--reference {
&::before {
position:absolute;
align-self: flex-start;
padding-right: 0.2rem;
height: .9rem;
width: .9rem;
margin-left: -1.15rem;
margin-top: -.1rem;
content: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iIzA4ZTVmZiI+PHBhdGggZD0iTSA0IDIgQyAzLjkwNSAyIDMuODE1NjA5NCAyLjAxNDM0MzggMy43MjQ2MDk0IDIuMDI3MzQzOCBDIDMuNDM0NjA5NCAyLjE0MzM0MzggMy4xMzk3MDMxIDIuMjU3MDkzOCAyLjg0NTcwMzEgMi4zNzEwOTM4IEMgMi4zMzQ3MDMxIDIuNzMzMDkzOCAyIDMuMzI2IDIgNCBMIDIgMTggTCA0IDE4IEwgNCA0IEwgMTggNCBMIDE4IDIgTCA0IDIgeiBNIDggNiBDIDYuODk1IDYgNiA2Ljg5NSA2IDggTCA2IDIwIEMgNiAyMS4xMDUgNi44OTUgMjIgOCAyMiBMIDIwIDIyIEMgMjEuMTA1IDIyIDIyIDIxLjEwNSAyMiAyMCBMIDIyIDggQyAyMiA2Ljg5NSAyMS4xMDUgNiAyMCA2IEwgOCA2IHogTSAxNyA4LjAwMTk1MzEgQyAxNy43NjggOC4wMDE5NTMxIDE4LjUzNjA5NCA4LjI5MzkwNjIgMTkuMTIxMDk0IDguODc4OTA2MiBDIDE5LjY4ODA5NCA5LjQ0NDkwNjMgMjAgMTAuMTk5IDIwIDExIEMgMjAgMTEuODAxIDE5LjY4ODA5NCAxMi41NTQwOTQgMTkuMTIxMDk0IDEzLjEyMTA5NCBMIDE3LjIyNDYwOSAxNS4wMTc1NzggTCAxNS44MTA1NDcgMTMuNjAzNTE2IEwgMTcuNzA3MDMxIDExLjcwNzAzMSBDIDE3Ljg5NjAzMSAxMS41MTgwMzEgMTggMTEuMjY3IDE4IDExIEMgMTggMTAuNzMzIDE3Ljg5NjAzMSAxMC40ODE5NjkgMTcuNzA3MDMxIDEwLjI5Mjk2OSBDIDE3LjMxNjAzMSA5LjkwMTk2ODcgMTYuNjgzOTY5IDkuOTAyOTY4OCAxNi4yOTI5NjkgMTAuMjkyOTY5IEwgMTQuMzkwNjI1IDEyLjE5NTMxMiBMIDE1LjgwNDY4OCAxMy42MDkzNzUgTCAxMy44MDA3ODEgMTUuNjEzMjgxIEwgMTUuMjE0ODQ0IDE3LjAyNzM0NCBMIDEzLjExOTE0MSAxOS4xMjEwOTQgQyAxMi41NTQxNDEgMTkuNjg3MDk0IDExLjgwMSAyMCAxMSAyMCBDIDEwLjE5OSAyMCA5LjQ0NDkwNjMgMTkuNjg4MDk0IDguODc4OTA2MiAxOS4xMjEwOTQgQyA4LjMxMjkwNjMgMTguNTU1MDk0IDggMTcuODAxIDggMTcgQyA4IDE2LjE5OSA4LjMxMjkwNjIgMTUuNDQ1OTA2IDguODc4OTA2MiAxNC44Nzg5MDYgTCAxMC45NzI2NTYgMTIuNzg1MTU2IEwgMTIuMzg2NzE5IDE0LjE5OTIxOSBMIDE0LjM2OTE0MSAxMi4yMTY3OTcgTCAxMi45NTUwNzggMTAuODAyNzM0IEwgMTQuODc4OTA2IDguODc4OTA2MiBDIDE1LjQ2MzkwNiA4LjI5MzkwNjIgMTYuMjMyIDguMDAxOTUzMSAxNyA4LjAwMTk1MzEgeiBNIDEyLjM3MzA0NyAxNC4yMTI4OTEgTCAxMC4yOTI5NjkgMTYuMjkyOTY5IEMgMTAuMTAzOTY5IDE2LjQ4MTk2OSAxMCAxNi43MzMgMTAgMTcgQyAxMCAxNy4yNjcgMTAuMTAzOTY5IDE3LjUxODAzMSAxMC4yOTI5NjkgMTcuNzA3MDMxIEMgMTAuNjcxOTY5IDE4LjA4NjAzMSAxMS4zMjgwMzEgMTguMDg1MDMxIDExLjcwNzAzMSAxNy43MDcwMzEgTCAxMy43ODcxMDkgMTUuNjI2OTUzIEwgMTIuMzczMDQ3IDE0LjIxMjg5MSB6IiBmaWxsPSIjMDhlNWZmIi8+PC9zdmc+Cg==');
}
}
&--target {
&::before {
position:absolute;
align-self: flex-start;
padding-right: 0.2rem;
height: .9rem;
width: .9rem;
margin-left: -1.15rem;
margin-top: -.1rem;
content: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iIzA4ZTVmZiI+PHBhdGggc3R5bGU9ImxpbmUtaGVpZ2h0Om5vcm1hbDt0ZXh0LWluZGVudDowO3RleHQtYWxpZ246c3RhcnQ7dGV4dC1kZWNvcmF0aW9uLWxpbmU6bm9uZTt0ZXh0LWRlY29yYXRpb24tc3R5bGU6c29saWQ7dGV4dC1kZWNvcmF0aW9uLWNvbG9yOiMwMDA7dGV4dC10cmFuc2Zvcm06bm9uZTtibG9jay1wcm9ncmVzc2lvbjp0Yjtpc29sYXRpb246YXV0bzttaXgtYmxlbmQtbW9kZTpub3JtYWwiIGQ9Ik0gNSAzIEMgMy45MDY5MzcyIDMgMyAzLjkwNjkzNzIgMyA1IEwgMyAxOSBDIDMgMjAuMDkzMDYzIDMuOTA2OTM3MiAyMSA1IDIxIEwgMTkgMjEgQyAyMC4wOTMwNjMgMjEgMjEgMjAuMDkzMDYzIDIxIDE5IEwgMjEgMTIgTCAxOSAxMiBMIDE5IDE5IEwgNSAxOSBMIDUgNSBMIDEyIDUgTCAxMiAzIEwgNSAzIHogTSAxNCAzIEwgMTQgNSBMIDE3LjU4NTkzOCA1IEwgOC4yOTI5Njg4IDE0LjI5Mjk2OSBMIDkuNzA3MDMxMiAxNS43MDcwMzEgTCAxOSA2LjQxNDA2MjUgTCAxOSAxMCBMIDIxIDEwIEwgMjEgMyBMIDE0IDMgeiIgZm9udC13ZWlnaHQ9IjQwMCIgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIHdoaXRlLXNwYWNlPSJub3JtYWwiIG92ZXJmbG93PSJ2aXNpYmxlIiBmaWxsPSIjMDhlNWZmIi8+PC9zdmc+Cg==');
}

View File

@@ -7,10 +7,10 @@
<script>
export default {
methods: {
goToHome(){
this.$router.push("/")
}
}
goToHome() {
this.$router.push('/')
},
},
}
</script>
@@ -26,16 +26,14 @@ export default {
cursor: pointer;
}
.gem {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNDggNDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwb2x5Z29uIGZpbGw9IiMwRDQ3QTEiIHBvaW50cz0iMzMsMTcgNDMsMTcgMjQsNDIgIi8+PHBvbHlnb24gZmlsbD0iIzg0RkZGRiIgcG9pbnRzPSI1LDE3IDE1LDUgMTUsMTcgIi8+PHBvbHlnb24gZmlsbD0iIzE5NzZEMiIgcG9pbnRzPSIzMyw1IDMzLDE3IDQzLDE3ICIvPjxnPjxwb2x5Z29uIGZpbGw9IiMwMDkxRUEiIHBvaW50cz0iMTUsMTcgMjMuOTk2LDQyLjE0OSAzMywxNyAiLz48cG9seWdvbiBmaWxsPSIjMDA5MUVBIiBwb2ludHM9IjE1LDUgMjQsNSAxNSwxNyAiLz48cG9seWdvbiBmaWxsPSIjMDA5MUVBIiBwb2ludHM9IjI0LDUgMzMsMTcgMzMsNSAiLz48L2c+PGc+PHBvbHlnb24gZmlsbD0iIzAwQjBGRiIgcG9pbnRzPSIzMywxNyAxNSwxNyAyNCw1ICIvPjxwb2x5Z29uIGZpbGw9IiMwMEIwRkYiIHBvaW50cz0iMzMsMTcgMzgsMTUgNDMsMTcgMzgsMTkgIi8+PC9nPjxnPjxwb2x5Z29uIGZpbGw9IiMwMEU1RkYiIHBvaW50cz0iMTUsMTcgNSwxNyAyMy45OTYsNDIuMTQ5ICIvPjxwb2x5Z29uIGZpbGw9IiMwMEU1RkYiIHBvaW50cz0iMTUsMTcgMjQsMTUgMzMsMTcgMjQsMTkgIi8+PC9nPjxwb2x5Z29uIGZpbGw9IiNFMEY3RkEiIHBvaW50cz0iNSwxNyAxMCwxNSAxNSwxNyAxMCwxOSAiLz48L3N2Zz4=);
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNDggNDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwb2x5Z29uIGZpbGw9IiMwRDQ3QTEiIHBvaW50cz0iMzMsMTcgNDMsMTcgMjQsNDIgIi8+PHBvbHlnb24gZmlsbD0iIzg0RkZGRiIgcG9pbnRzPSI1LDE3IDE1LDUgMTUsMTcgIi8+PHBvbHlnb24gZmlsbD0iIzE5NzZEMiIgcG9pbnRzPSIzMyw1IDMzLDE3IDQzLDE3ICIvPjxnPjxwb2x5Z29uIGZpbGw9IiMwMDkxRUEiIHBvaW50cz0iMTUsMTcgMjMuOTk2LDQyLjE0OSAzMywxNyAiLz48cG9seWdvbiBmaWxsPSIjMDA5MUVBIiBwb2ludHM9IjE1LDUgMjQsNSAxNSwxNyAiLz48cG9seWdvbiBmaWxsPSIjMDA5MUVBIiBwb2ludHM9IjI0LDUgMzMsMTcgMzMsNSAiLz48L2c+PGc+PHBvbHlnb24gZmlsbD0iIzAwQjBGRiIgcG9pbnRzPSIzMywxNyAxNSwxNyAyNCw1ICIvPjxwb2x5Z29uIGZpbGw9IiMwMEIwRkYiIHBvaW50cz0iMzMsMTcgMzgsMTUgNDMsMTcgMzgsMTkgIi8+PC9nPjxnPjxwb2x5Z29uIGZpbGw9IiMwMEU1RkYiIHBvaW50cz0iMTUsMTcgNSwxNyAyMy45OTYsNDIuMTQ5ICIvPjxwb2x5Z29uIGZpbGw9IiMwMEU1RkYiIHBvaW50cz0iMTUsMTcgMjQsMTUgMzMsMTcgMjQsMTkgIi8+PC9nPjxwb2x5Z29uIGZpbGw9IiNFMEY3RkEiIHBvaW50cz0iNSwxNyAxMCwxNSAxNSwxNyAxMCwxOSAiLz48L3N2Zz4=);
background-size: cover;
width:35px;
height:35px;
width: 35px;
height: 35px;
}
p {
margin: 0 0 0 .3rem;
margin: 0 0 0 0.3rem;
font-size: 14px;
}
}
</style>

View File

@@ -10,32 +10,34 @@
</template>
<script>
import { mapMutations } from "vuex";
import { mapMutations } from 'vuex'
export default {
data() {
return {
categories: [{ slug: "", title: "" }]
};
categories: [{ slug: '', title: '' }],
}
},
computed: {
areCardsVisible() {
return this.$store.getters['Sidebar/areCardsVisible']
}
},
},
created() {
this.categories = this.$store.getters['data/resources'].map(({ title, slug }) => ({ title, slug }))
},
methods: {
...mapMutations({
toggleCardsVisible: "Sidebar/toggleCardsVisible"
})
}
};
toggleCardsVisible: 'Sidebar/toggleCardsVisible',
}),
},
}
</script>
<style lang="scss" scoped>
.sidebar {
position: sticky;
top: 10px;
display: grid;
grid-template-columns: 1fr;
font-size: 14px;

View File

@@ -5,15 +5,19 @@
td.tableRow--links
tr
td
a.tableRow--reference(@click='createCopyUrl(resource)') Copy
a.tableRow--reference(@click="createCopyUrl(resource)") Copy
td
a.tableRow--target(:href="resource.url" :target='resource.title' rel='noreferrer') Open
</template>
<script>
export default {
props: ['resource', 'isActive', 'createCopyUrl'],
};
props: {
resource: Object,
isActive: Boolean,
createCopyUrl: Function,
},
}
</script>

View File

@@ -17,8 +17,8 @@ export default {
Github,
Logo,
Search,
Sidebar
}
Sidebar,
},
}
</script>
@@ -99,6 +99,35 @@ h1 {
grid-gap: 1rem;
}
// Fade in title and cards and rows
.fade-title {
&-enter {
opacity: 0;
&-to {
opacity: 1;
}
&-active {
transition: opacity .1s ease-in-out;
}
}
}
.fade-card {
&-enter {
opacity: 0;
&-to {
opacity: 1;
}
&-active {
transition: opacity .1s ease-in-out;
}
}
}
@media (max-width: 400px) {
.layout {

View File

@@ -18,18 +18,34 @@ export default {
{ rel:'manifest', href:'/site.webmanifest' },
{ rel:'icon', type:'image/png', sizes:'16x16', href:'/favicon-16x16.png' },
{ rel:'icon', type:'image/png', sizes:'32x32', href:'/favicon-32x32.png' },
{ rel:'apple-touch-icon', sizes:'76x76', href:'/apple-touch-icon.png' }
{ rel:'apple-touch-icon', sizes:'76x76', href:'/apple-touch-icon.png' },
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
],
},
/*
** Generate dynamic routes
*/
generate: {
routes: resources.map(category => category.slug)
routes: resources.map(category => category.slug),
},
/**
* Configure ESLint to run on save with hot reloading
*/
build: {
extend(config, ctx) {
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/,
})
}
},
},
/*
@@ -38,12 +54,12 @@ export default {
loading: { color: '#fff' },
plugins: [
'~/plugins/i18n.js'
'~/plugins/i18n.js',
],
/*
** Nuxt.js modules
*/
modules: [
'nuxt-clipboard2',
]
],
}

781
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,9 @@
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore ."
},
"dependencies": {
"cross-env": "^5.2.0",
@@ -18,8 +20,15 @@
},
"devDependencies": {
"autoprefixer": "^8.6.4",
"babel-eslint": "^10.0.3",
"eslint": "^6.5.1",
"eslint-config-prettier": "^6.3.0",
"eslint-loader": "^3.0.2",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^5.2.3",
"node-sass": "^4.12.0",
"nodemon": "^1.18.9",
"prettier": "^1.18.2",
"pug": "^2.0.3",
"pug-plain-loader": "^1.0.0",
"sass-loader": "^7.1.0",

View File

@@ -1,25 +1,31 @@
<template lang="pug">
div
h1 {{ category.title }}
.cards(v-if="areCardsVisible")
template(v-for='resource in category.resources' )
Card(:resource='resource' :key='resource.title' :createCopyUrl="createCopyUrl" :isActive='activeCard === resource.cleanTitle')
table(v-if="!areCardsVisible")
template(v-for='resource in category.resources' )
TableRow(:resource='resource' :key='resource.title' :createCopyUrl="createCopyUrl" :isActive='activeCard === resource.cleanTitle')
transition(name="fade-title" @after-enter="afterEnter")
h1(v-if="showTitle") {{ category.title }}
transition(name="fade-card")
.cards(v-if="areCardsVisible && showCards")
template(v-for='resource in category.resources' )
Card(:resource='resource' :key='resource.title' :createCopyUrl="createCopyUrl" :isActive='activeCard === resource.cleanTitle')
transition(name="fade-card")
table(v-if="!areCardsVisible && showCards")
template(v-for='resource in category.resources' )
TableRow(:resource='resource' :key='resource.title' :createCopyUrl="createCopyUrl" :isActive='activeCard === resource.cleanTitle')
</template>
<script>
import Card from "../components/Card";
import TableRow from "../components/TableRow";
import Card from '../components/Card'
import TableRow from '../components/TableRow'
export default {
components: { Card, TableRow },
data() {
return {
categoryRouteTitle: this.$route.params.category,
index: '',
activeCard: '',
};
showTitle: false,
showCards: false,
}
},
computed: {
areCardsVisible() {
@@ -29,6 +35,12 @@ export default {
return this.$store.getters['data/sortByTitle'](this.categoryRouteTitle)
},
},
created() {
this.activeCard = this.$route.query.card || ''
},
mounted() {
this.showTitle = true
},
methods: {
setActiveCard(index) {
this.activeCard = index
@@ -40,15 +52,14 @@ export default {
this.setActiveCard(cleanTitle)
this.$router.push(path)
} catch (e) {
console.error(e);
console.error(e)
}
}
},
afterEnter() {
this.showCards = true
},
},
created() {
this.activeCard = this.$route.query.card || ''
},
components: { Card, TableRow }
};
}
</script>
<style lang="scss" scoped>

View File

@@ -11,8 +11,8 @@ export default ({ app, store }) => {
fallbackLocale: 'en',
messages: {
'en': require('~/locales/en.json'),
'fr': require('~/locales/fr.json')
}
'fr': require('~/locales/fr.json'),
},
})
app.i18n.path = (link) => {

View File

@@ -1,7 +1,5 @@
const join = require('path').join
module.exports = {
plugins: [
require('autoprefixer')
]
require('autoprefixer'),
],
}

View File

@@ -6,133 +6,133 @@
"title": "CSS Grid Generator",
"desc": "Visually create your css grid and export the code.",
"url": "https://cssgrid-generator.netlify.com/",
"tags": []
"tags": ["generator", "grid", "layout", "visual tool"]
},
{
"title": "Keyframes Editor",
"desc": "An insanely simple way to create CSS animations",
"url": "https://keyframes.app/editor/",
"tags": []
"tags": ["generator", "animation", "visual tool"]
},
{
"title": "Flexbox Froggy",
"desc": "A game to learn Flexbox",
"url": "https://flexboxfroggy.com",
"tags": []
"tags": ["educational", "beginner"]
},
{
"title": "Flexbox Zombies",
"desc": "A course to learn Flexbox",
"url": "https://mastery.games/p/flexbox-zombies",
"tags": []
"tags": ["educational", "beginner"]
},
{
"title": "CSS Gridgarden",
"desc": "A game to learn Grid",
"url": "https://cssgridgarden.com",
"tags": []
"tags": ["educational", "beginner"]
},
{
"title": "30 Seconds of Code",
"desc": "A curated collection of useful CSS snippets you can understand in 30 seconds or less.",
"url": "https://30-seconds.github.io/30-seconds-of-css/",
"tags": []
"tags": ["tips", "tricks", "collection"]
},
{
"title": "Grid by example",
"desc": "Everything you need to learn CSS Grid Layout",
"url": "https://gridbyexample.com/learn/",
"tags": []
"tags": ["example", "showcase", "educational"]
},
{
"title": "BEM naming convention",
"desc": "Block Element Modifier is a methodology that helps you to create reusable components and code sharing in front-end development",
"url": "https://getbem.com/",
"tags": []
"tags": ["convention", "naming", "structure"]
},
{
"title": "CSS Triggers",
"desc": "Overview of css attributes which trigger either layout, paint or composite. Good to know if you want to learn more about css performance.",
"url": "https://csstriggers.com/",
"tags": []
"tags": ["performance", "rendering"]
},
{
"title": "A complete guide to flexbox",
"desc": "A comprehensive guide to flexbox, focusing on all the different possible properties for the parent element (the flex container).",
"url": "https://css-tricks.com/snippets/css/a-guide-to-flexbox/",
"tags": []
"tags": ["guide", "educational"]
},
{
"title": "Learn CSS layout",
"desc": "This site teaches the CSS fundamentals that are used in any website's layout (Unfortunately nothing abour display:grid yet).",
"desc": "This site teaches the CSS fundamentals that are used in any website's layout.",
"url": "http://learnlayout.com",
"tags": []
"tags": ["layout", "educational", "beginner"]
},
{
"title": "CSSmatic - box shadow generator",
"desc": "The ultimate box shadow generator",
"url": "https://www.cssmatic.com/box-shadow",
"tags": []
"tags": ["generator", "visual tool"]
},
{
"title": "AirBnB CSS / Sass Styleguide",
"desc": "A mostly reasonable approach to css and sass.",
"url": "https://github.com/airbnb/css",
"tags": []
"tags": ["structure", "styleguide", "convention"]
},
{
"title": "Animista",
"desc": "CSS animations on demand.",
"url": "http://animista.net/",
"tags": []
"tags": ["animation", "collection", "generator", "visual tool"]
},
{
"title": "Use CSS Grids the right way",
"desc": "CSS Grid is robust, flexible, and a refreshing paradigm shift from other CSS layout systems. While these are selling points for Grid, they also make it hard to learn.",
"url": "https://vgpena.github.io/using-css-grid-the-right-way/",
"tags": []
"tags": ["guide", "educational"]
},
{
"title": "CSS Protips",
"desc": "A collection of tips to help take your CSS skills pro.",
"url": "https://github.com/AllThingsSmitty/css-protips#readme",
"tags": []
"tags": ["collection", "tips", "tricks"]
},
{
"title": "Flexbox Defense",
"desc": "Your job is to stop the incoming enemies from getting past your defenses. Unlike other tower defense games, you must position your towers using CSS!",
"url": "http://www.flexboxdefense.com/",
"tags": []
"tags": ["educational", "beginner"]
},
{
"title": "CSS Diner",
"desc": "Learn CSS selectors while playing a game.",
"url": "https://flukeout.github.io/",
"tags": []
"tags": ["educational", "beginner"]
},
{
"title": "CSS Animation",
"desc": "CSS animation articles, tips and tutorials. Level Up Your CSS Animation Skills.",
"url": "https://cssanimation.rocks/",
"tags": []
"tags": ["collection", "guide", "educational"]
},
{
"title": "JustREM",
"desc": "Easily and quickly convert pixel values into rem values.",
"url": "https://justrem.xyz/",
"tags": []
"tags": ["units"]
},
{
"title": "(Re)learn css layout",
"desc": "If you find yourself wrestling with CSS layout, its likely youre making decisions for browsers they should be making themselves. Through a series of simple, composable layouts, Every Layout will teach you how to better harness the built-in algorithms that power browsers and CSS.",
"url": "https://every-layout.dev/",
"tags": []
"tags": ["educational", "guide"]
},
{
"title": "Interactive CSS box-model view",
"desc": "Learn CSS box-model by interractively changing the values.",
"url": "https://codepen.io/carolineartz/full/ogVXZj",
"tags": []
"tags": ["visual tool", "educational", "beginner"]
}
]
}

View File

@@ -6,43 +6,43 @@
"title": "dev.to",
"desc": "Where programmers share ideas and help each other grow. It is an online community for sharing and discovering great ideas, having debates, and making friends.",
"url": "https://www.dev.to",
"tags": []
"tags": ["community", "reading"]
},
{
"title": "CSS Tricks",
"desc": "Daily webdev related articles, snippets and guides since 2007",
"url": "https://css-tricks.com/",
"tags": []
"tags": ["reading", "educational", "design"]
},
{
"title": "Smashing magazine",
"desc": "Founded in September 2006 in Germany, Smashing Magazine delivers reliable, useful, but most importantly practical articles to web designers and developers. ",
"url": "https://www.smashingmagazine.com/",
"tags": []
"tags": ["reading", "educational", "design", "development"]
},
{
"title": "Hackernews",
"desc": "Hacker News is a social news website focusing on computer science and entrepreneurship.",
"url": "https://news.ycombinator.com/",
"tags": []
"tags": ["forum", "development", "reading"]
},
{
"title": "Producthunt",
"desc": "Check popular new products out and get inspired, maybe even post yours?",
"url": "https://www.producthunt.com/",
"tags": []
"tags": ["discover", "explore"]
},
{
"title": "dailydevlinks",
"desc": "Fresh, daily links so you can keep up-to-date with everything developer ",
"url": "https://dailydevlinks.com/",
"tags": []
"tags": ["development", "reading"]
},
{
"title": "Sidebar.io",
"desc": "The five best design links, every day.",
"url": "https://sidebar.io/",
"tags": []
"tags": ["design", "reading"]
}
]
}

30
resources/icons.json Normal file
View File

@@ -0,0 +1,30 @@
{
"title": "Icons",
"slug": "/icons",
"resources": [
{
"title": "Font awesome",
"desc": "CSS and LESS based font and icon toolkit.",
"url": "https://fontawesome.com/",
"tags": []
},
{
"title": "Icomoon",
"desc": "IcoMoon provides a package of vector icons, along with a free HTML5 app for making custom icon fonts or SVG sprites.",
"url": "https://icomoon.io/",
"tags": []
},
{
"title": "Icons8",
"desc": "Get free icons designed to combine perfectly and fit into the style of your design.",
"url": "https://icons8.com/",
"tags": []
},
{
"title": "Material Icons",
"desc": "Material icons are delightful, beautifully crafted symbols for common actions and items. Download on desktop to use them in your digital products for Android, iOS, and web.",
"url": "https://material.io/resources/icons",
"tags": []
}
]
}

View File

@@ -12,6 +12,7 @@ import python from './python'
import ruby from './ruby'
import server from './server'
import utility from './utility'
import icons from './icons'
export default [
css,
@@ -28,4 +29,5 @@ export default [
ruby,
server,
utility,
]
icons,
]

View File

@@ -163,6 +163,12 @@
"desc": "Let's Encrypt is a free, automated, and open certificate authority brought to you by the non-profit Internet Security Research Group (ISRG).",
"url": "https://letsencrypt.org/",
"tags": []
},
{
"title": "Mailhog",
"desc": "Web and API based SMTP testing.",
"url": "https://github.com/mailhog/MailHog",
"tags": []
}
]
}
}

View File

@@ -1,14 +1,14 @@
export const state = () => ({
areCardsVisible: true
areCardsVisible: true,
})
export const getters = {
areCardsVisible: state => state.areCardsVisible
areCardsVisible: state => state.areCardsVisible,
}
export const mutations = {
toggleCardsVisible(state) {
if (process.browser) localStorage.setItem('areCardsVisible', !state.areCardsVisible)
state.areCardsVisible = !state.areCardsVisible
}
},
}

View File

@@ -5,20 +5,20 @@ if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, 'flat', {
configurable: true,
value: function flat () {
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]);
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0])
return depth ? Array.prototype.reduce.call(this, function (acc, cur) {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1));
acc.push.apply(acc, flat.call(cur, depth - 1))
} else {
acc.push(cur);
acc.push(cur)
}
return acc;
}, []) : Array.prototype.slice.call(this);
return acc
}, []) : Array.prototype.slice.call(this)
},
writable: true
});
writable: true,
})
}
/**
@@ -39,14 +39,14 @@ export const state = () => ({
cleanTitle,
path: `${category.slug}?card=${cleanTitle}`,
}
})
}),
})),
// List of all tags, duplicates removed
tags: [...new Set(
resources
.map(resource => resource.resources).flat()
.map(resource => resource.tags).flat()
)]
)],
})
export const getters = {
@@ -64,9 +64,9 @@ export const getters = {
const clone = [...category.resources]
return {
...category,
resources: clone.sort(compareTitles)
resources: clone.sort(compareTitles),
}
}
},
}
const compareTitles = (x, y) => {

View File

@@ -1,6 +1,6 @@
export const state = () => ({
locales: ['en', 'fr', 'de'],
locale: 'en'
locale: 'en',
})
export const mutations = {
@@ -8,5 +8,5 @@ export const mutations = {
if (state.locales.indexOf(locale) !== -1) {
state.locale = locale
}
}
},
}