diff --git a/store/data.js b/store/data.js index a103289..25f9e79 100644 --- a/store/data.js +++ b/store/data.js @@ -1,4 +1,4 @@ -import resources from '../resources' +import categories from '../resources' import * as R from 'ramda' import { getAllResources, @@ -7,22 +7,18 @@ import { partiallyIncludesElOf, tagsNotEmpty, cleanString, + addCleanTitleAndPath, } from '../utils/pure' -export const state = () => ({ - resources: resources.map(category => ({ - ...category, - resources: category.resources.map(resource => { - const cleanTitle = resource.title.replace(/ /g, '').toLowerCase() - return { - ...resource, - cleanTitle, - path: `${category.slug}?card=${cleanTitle}`, - } - }), - })), - tags: getAllTags(resources), -}) +export const state = () => { + const resourcesLens = R.lens(R.prop('resources'), R.assoc('resources')) + return { + resources: R.map(category => + R.over(resourcesLens, R.map(addCleanTitleAndPath(category.slug)), category), + categories), + tags: getAllTags(categories), + } +} export const getters = { tags: R.prop('tags'), diff --git a/test/output.json b/test/output.json new file mode 100644 index 0000000..cccfd51 --- /dev/null +++ b/test/output.json @@ -0,0 +1,86 @@ +[ + { + "title": "CSS", + "slug": "/css", + "resources": [ + { + "title": "CSS Grid Generator", + "desc": "Visually create your css grid and export the code.", + "url": "https://cssgrid-generator.netlify.com/", + "tags": [ + "generator", + "grid", + "layout", + "visual tool" + ], + "cleanTitle": "cssgridgenerator", + "path": "/css?card=cssgridgenerator" + }, + { + "title": "Keyframes Editor", + "desc": "An insanely simple way to create CSS animations", + "url": "https://keyframes.app/editor/", + "tags": [ + "generator", + "animation", + "visual tool" + ], + "cleanTitle": "keyframeseditor", + "path": "/css?card=keyframeseditor" + }, + { + "title": "Flexbox Froggy", + "desc": "A game to learn Flexbox", + "url": "https://flexboxfroggy.com", + "tags": [ + "educational", + "beginner" + ], + "cleanTitle": "flexboxfroggy", + "path": "/css?card=flexboxfroggy" + } + ] + }, + { + "title": "Design", + "slug": "/design", + "resources": [ + { + "title": "UX/UI Designer Roadmap 2017", + "desc": "Roadmap to becoming a UI/UX Designer in 2017", + "url": "https://github.com/togiberlin/ui-ux-designer-roadmap", + "tags": [ + "career", + "ui", + "ux" + ], + "cleanTitle": "ux/uidesignerroadmap2017", + "path": "/design?card=ux/uidesignerroadmap2017" + }, + { + "title": "Undraw", + "desc": "Free vector illustrations for your website.", + "url": "https://undraw.co", + "tags": [ + "illustration", + "svg", + "ui" + ], + "cleanTitle": "undraw", + "path": "/design?card=undraw" + }, + { + "title": "Practical UI tips", + "desc": "7 Tips to boost your UI design.", + "url": "https://medium.com/refactoring-ui/7-practical-tips-for-cheating-at-design-40c736799886", + "tags": [ + "ui", + "tips", + "tricks" + ], + "cleanTitle": "practicaluitips", + "path": "/design?card=practicaluitips" + } + ] + } +] \ No newline at end of file diff --git a/test/pure.test.js b/test/pure.test.js index e45911c..45b055c 100644 --- a/test/pure.test.js +++ b/test/pure.test.js @@ -26,4 +26,4 @@ test('partiallyIncludesElOf 2', () => { test('partiallyIncludesElOf 3', () => { expect(P.partiallyIncludesElOf(['aa', 'b'], ['c'])).toBeFalsy -}) \ No newline at end of file +}) diff --git a/utils/pure.js b/utils/pure.js index 68ee503..b9bdcd7 100644 --- a/utils/pure.js +++ b/utils/pure.js @@ -2,20 +2,20 @@ import * as R from 'ramda' /// Types -const Category = { - title: String, - slug: String, - resources: [Resource], -} +// const Category = { +// title: String, +// slug: String, +// resources: [Resource], +// } -const Resource = { - title: String, - cleanTitle: String, - desc: String, - path: String, - url: String, - tags: [String], -} +// const Resource = { +// title: String, +// cleanTitle: String, +// desc: String, +// path: String, +// url: String, +// tags: [String], +// } /// Functions // isNotEmpty [a] -> Bool @@ -38,6 +38,9 @@ export const tagsNotEmpty = R.compose(isNotEmpty, R.prop('tags')) // cleanString :: String -> String export const cleanString = R.compose(R.toLower, R.trim) +// removeSpacesLower :: String -> String +export const cleanStringAndRemoveSpaces = R.compose(R.replace(/ /g, ''), cleanString) + // true if list2 has element that appears in list1 else false // includesElOf :: [a] -> [a] -> Bool export const includesElOf = R.curry((list1, list2) => R.any(el => R.includes(el, list2), list1)) @@ -49,3 +52,13 @@ export const partiallyIncludesElOf = R.curry((list1, list2) => R.any(R.includes(el2), list1), list2) ) + +// addCleanTitleAndPath :: Object -> Resource +export const addCleanTitleAndPath = R.curry((slug, obj) => { + const cleanTitle = cleanStringAndRemoveSpaces(obj.title) + return { + ...obj, + cleanTitle, + path: `${slug}?card=${cleanTitle}`, + } +}) \ No newline at end of file