Skip to content
This repository has been archived by the owner on Feb 4, 2022. It is now read-only.

Commit

Permalink
Sandbox cards have some cool new methods for content
Browse files Browse the repository at this point in the history
  • Loading branch information
cnocon committed Aug 17, 2020
1 parent b1af24f commit 3a140ed
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 94 deletions.
110 changes: 45 additions & 65 deletions gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,24 @@ const path = require(`path`);
const sandboxData = require('./queries/sandboxData');
const { postCategoriesDataQuery } = require('./queries/postCategoriesData');
const { allPostsDataQuery } = require('./queries/allPostsData');

const chunkArray = (array, size) => {
if (!array) return [];
const firstChunk = array.slice(0, size);
if (!firstChunk.length) return array; // base case/terminates recursion
return [firstChunk].concat(chunkArray(array.slice(size, array.length), size));
}
const { chunkArray } = require('./helpers/chunkArray');

exports.createPages = async ({ actions, graphql }) => {
const categoriesData = await graphql(postCategoriesDataQuery);
const allPostsData = await graphql(allPostsDataQuery);
const allPosts = allPostsData.data.allButterPost.edges.reverse();
const chunkedPosts = chunkArray(allPosts, 3);
const groups = allPostsData.data.allButterPost.group;
const categoryGroups = allPostsData.data.allButterPost.group;

groups.forEach(group => {
const sortedPosts = group.nodes.sort((a, b) => a.published < b.published)
/**
* CATEGORY PAGES
*
* 3 posts per page (unlimited pages per category)
*/
categoryGroups.forEach(categoryGroup => {
const sortedPosts = categoryGroup.nodes.sort((a, b) => a.published < b.published)
const chunkedPosts = chunkArray(sortedPosts, 3);
const category = group.fieldValue.toLowerCase().replace(/\s/g, '-')
const category = categoryGroup.fieldValue.toLowerCase().replace(/\s/g, '-')

chunkedPosts.forEach((collection, index) => {
actions.createPage({
Expand All @@ -35,30 +34,26 @@ exports.createPages = async ({ actions, graphql }) => {
categories: categoriesData.data.allButterPost.distinct,
prevPagePath: index < 1 ? null : `/articles/${category}/page-${index}`,
nextPagePath: index + 1 === chunkedPosts.length ? null : `/articles/${category}/page-${index + 2}`,
title: `Posted in ${group.fieldValue}`,
title: `Posted in ${categoryGroup.fieldValue}`,
stitle: `Latest Posts | Front End Development Blog`,
seoDescription: `Latest ${group.fieldValue} posts from Cristin O'Connor's Front End Development Blog`,
seoDescription: `Latest ${categoryGroup.fieldValue} posts from Cristin O'Connor's Front End Development Blog`,
category: category,
posts: collection.reverse(),
breadcrumbs: [
{
name: 'Home',
path: '/',
},
{
name: `Blog`,
path: `/articles/page-1`,
},
{
name: category.charAt(0).toUpperCase() + category.slice(1),
path: null,
},
{name: 'Home', path: '/'},
{name: `Blog`,path: `/articles/page-1`},
{name: category.charAt(0).toUpperCase() + category.slice(1), path: null},
]
},
})
})
})

/**
* LATEST POST PAGES
*
* 3 posts per page
*/
chunkedPosts.forEach((collection, index) => {
actions.createPage({
path: `/articles/page-${index + 1}`,
Expand All @@ -72,23 +67,18 @@ exports.createPages = async ({ actions, graphql }) => {
stitle: "Latest Posts | Front End Development Blog",
seoDescription: `Latest Posts from Cristin O'Connor's Front End Development Blog`,
breadcrumbs: [
{
name: 'Home',
path: '/',
},
{
name: `Blog`,
path: `/articles/page-1`,
},
{
name: `Page ${index + 1}`,
path: null,
},
{name: 'Home', path: '/'},
{name: `Blog`, path: `/articles/page-1`},
{name: `Page ${index + 1}`, path: null},
],
},
})
})

/**
* POST SINGLE PAGES
*
*/
allPosts.forEach(( node, index ) => {
actions.createPage({
path: `/articles/${node.node.slug}`,
Expand All @@ -99,48 +89,38 @@ exports.createPages = async ({ actions, graphql }) => {
prevPost: index === 0 ? null : allPosts[index - 1].node,
nextPost: index === allPosts.length - 1 ? null : allPosts[index + 1].node,
categories: categoriesData.data.allButterPost.distinct,
colors: ['blue', 'green', 'purple', 'blue'],
breadcrumbs: [
{
name: 'Home',
path: '/',
},
{
name: `Blog`,
path: `/articles/page-1`,
},
{
name: node.node.title,
path: null,
},
{ name: 'Home', path: '/'},
{ name: `Blog`, path: `/articles/page-1`},
{ name: node.node.title, path: null},
],
},
})
})

actions.createPage({
path: `/sandbox`,
component: path.resolve(`./src/components/Sandbox/Sandbox.jsx`),
context: {
sandboxData: sandboxData
},
})

/**
* ABOUT ME PAGE
*
*/
actions.createPage({
path: `/`,
component: path.resolve(`./src/components/AboutMe/AboutMe.jsx`),
context: {
posts: allPosts.slice(0,6),
posts: allPosts.slice(0, 6),
categories: categoriesData.data.allButterPost.distinct,
breadcrumbs: [
{
name: 'Home',
path: null,
},
],
breadcrumbs: [{name: 'Home', path: null}],
},
})

/**
* SANDBOX PAGE FOR Q-AND-API DATA
*
*/
actions.createPage({
path: `/sandbox`,
component: path.resolve(`./src/components/Sandbox/Sandbox.jsx`),
context: {sandboxData: sandboxData},
})
}

// You can delete this file if you're not using it
Expand Down
8 changes: 8 additions & 0 deletions helpers/chunkArray.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const chunkArray = (array, size) => {
if (!array) return [];
const firstChunk = array.slice(0, size);
if (!firstChunk.length) return array; // base case/terminates recursion
return [firstChunk].concat(chunkArray(array.slice(size, array.length), size));
}

exports.chunkArray = chunkArray;
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "gatsby-starter-default",
"private": true,
"description": "A simple starter to get up and developing quickly with Gatsby",
"version": "0.1.0",
"author": "Kyle Mathews <[email protected]>",
"name": "cristin-io",
"private": false,
"description": "Cristin O'Connor's Front End Development Blog and Portfolio Site",
"version": "1.0.0",
"author": "Cristin O'Connor <[email protected]>",
"dependencies": {
"@emotion/core": "^10.0.28",
"@emotion/styled": "^10.0.27",
Expand Down
12 changes: 5 additions & 7 deletions queries/sandboxData.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,16 @@ const dataPromise = new Promise((resolve, reject) => {
[{path: `/categories/${id}`, key: 'category'},
{path: `/categories/${id}/questions`, key: 'categoryQuestions'}
].forEach(set => {
const options = {
'hostname': 'arcane-stream-45843.herokuapp.com',
'path': set.path,
'headers': { 'Content-Type': 'application/json' }
};
const options = {'path': set.path, 'hostname': 'arcane-stream-45843.herokuapp.com', 'headers': { 'Content-Type': 'application/json' }};
https.get(options, res => {
const chunks = [];
res.on("data", chunk => chunks.push(chunk));
res.on("end", () => {
sandboxData[`${id}`] = {};
if (!sandboxData[id]) {
sandboxData[id] = {};
}
const str = Buffer.concat(chunks).toString();
sandboxData[`${id}`][set.key] = JSON.parse(str);
sandboxData[id][set.key] = JSON.parse(str);
if (i === categoryIds.length - 1) {
resolve(sandboxData);
};
Expand Down
80 changes: 80 additions & 0 deletions src/components/FlashCard/FlashCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { useState } from 'react'
import EmbeddedGist from '../EmbeddedGist/EmbeddedGist'
import ReactHtmlParser from 'react-html-parser'
import * as Styled from './FlashCard.styles'
import SEO from "../SEO/seo"

const Snippet = ({item}) => {
const { lines, lang } = item;
const compiledLines = lines.map(line => line).join("\n");

return (
<pre className="prettyprint"><code className={`lang-${lang}`}>
{ReactHtmlParser(compiledLines)}
</code></pre>
)
}

const FlashCard = ({...props}) => {
const { question, name } = props;
const [ visible, setVisible ] = useState(props.visible);

const generateAnswerMedia = item => {
switch (item.type) {
case 'image':
return <img
src={item.url}
alt={item.desc}
style={{width: `${item.width}px`}}
key={item.url} />;
case 'gist':
return <EmbeddedGist gist={item.gist} key={item.id}/>;
case 'snippet':
console.log(item);
return <Snippet item={item} key={Math.random()} />;
default:
// do nothing
}
}

const answerMedia = question.answer_media.map(item => {
return generateAnswerMedia(item);
});

const style = visible ? {display: 'block'} : { display: 'none'};

return (
<div className="flashcard" style={style} css={Styled.Card}>
<SEO stitle='Sandbox' sdescription='Testing out the Q-and-API API I built using Node and Express' slug="sandbox">
<script defer async src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=doxy"></script>
</SEO>
{/* <img src={imgPath} width={300} alt="" role="presentation"/> */}
{/* <EmbeddedGist gist={`cnocon/25c10c5a228ef004de9ca54fe64f7411`} /> */}
{/* <h4>Prompt:</h4> {ReactHtmlParser(test.prompt)} */}
{/* <h4>Answer:</h4> {ReactHtmlParser(test.answer)} */}

<section className="front">
<header>
<h2>Question</h2>
<h4>Category: {name}</h4>
</header>
{ReactHtmlParser(question.prompt)}
<footer><h5>Difficulty: {question.difficulty}/10</h5></footer>
</section>

<section className="back">
<header>
<h2>Answer</h2>
<h4>Category: {name}</h4>
</header>
{ReactHtmlParser(question.answer)}
{answerMedia}
<footer><h5>Difficulty: {question.difficulty}/10</h5></footer>
</section>


</div>
);
};

export default FlashCard;
31 changes: 31 additions & 0 deletions src/components/FlashCard/FlashCard.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// import styled from "@emotion/styled"
import { css } from "@emotion/core"
import Theme from '../Theme/Theme'

export const Card = css`
line-height: ${Theme.fonts.sizes.lineHeights.sm};
border: 3px solid ${Theme.colors.grays.border};
border-radius: 3px;
padding: ${Theme.spacing.default} ${Theme.spacing.default} 0;
margin: 60px auto 0;
max-width: 600px;
pre:not(.prettyprint) {
display: inline-block;
line-height: inherit;
background-color: ${Theme.colors.grays.background};
padding: 1px 6px;
margin: 0;
}
pre > code span {
font-size: 12px;
}
footer {
border-top: 2px solid ${Theme.colors.grays.border};
background-color: ${Theme.colors.grays.border};
padding: 10px 15px;
margin: 20px -16px 0;
}
`
35 changes: 18 additions & 17 deletions src/components/Sandbox/Sandbox.jsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import React from 'react'
import EmbeddedGist from '../EmbeddedGist/EmbeddedGist'
import Layout from "../Layout/Layout"
import ReactHtmlParser from 'react-html-parser'
import SEO from "../SEO/seo"
import Header from "../Header/Header"
// import IconList from "../IconList/IconList"
// import SectionTitle from '../SectionTitle/SectionTitle'
// import IconColumn from '../IconColumn/IconColumn'
// import ImageColumn from '../ImageColumn/ImageColumn'
// import PageTransition from '../../../plugins/gatsby-v3-plugin-page-transitions';
import FlashCard from "../FlashCard/FlashCard"
import Layout from "../Layout/Layout"

const Sandbox = ({ ...data }) => {
const { sandboxData } = data.pageContext;
console.log(sandboxData);
// const imgPath = sandboxData[3].questions[1].answer_media[0].image;
// const gistPath = sandboxData[0].questions[2].answer_media[0].gist;
// const test = sandboxData[0].questions[0];
// console.log(sandboxData);

const cardData = Object.values(sandboxData).map((object, i) => {
const { _id, name, slug } = object.category;
return object.categoryQuestions.questions.map(question => {
return {id: _id, name: name, slug: slug, question: question};
})
}).flat();

const cards = cardData.map((card, i) => {
const { id, name, slug, question } = card;
// const visible = question.answer_media.length > 0 ? true : false;
const visible = true;
return <FlashCard key={i} id={id} question={question} slug={slug} visible={visible} name={name} />;
});

return (
<Layout>
<Header />
<SEO stitle="API Sandbox" robots="noindex"/>
<div className="row">
<div className="col-sm-12">
{/* <img src={imgPath} width={300} alt="" role="presentation"/> */}
{/* <EmbeddedGist gist={`cnocon/25c10c5a228ef004de9ca54fe64f7411`} /> */}
{/* <h4>Prompt:</h4> {ReactHtmlParser(test.prompt)} */}
{/* <h4>Answer:</h4> {ReactHtmlParser(test.answer)} */}
{ cards }
</div>
</div>
</Layout>
Expand Down

0 comments on commit 3a140ed

Please sign in to comment.