From 4d9923854d29ce49ceb3c781ba2203fd9365d433 Mon Sep 17 00:00:00 2001 From: Nick Pegg Date: Sat, 7 Oct 2017 14:26:23 -0700 Subject: [PATCH] Re-jigger articles There's now a base Article class, and then FullArticle and Articles classes which are what react-router routes to --- src/App.js | 8 ++-- src/Article.js | 125 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 97 insertions(+), 36 deletions(-) diff --git a/src/App.js b/src/App.js index 70fcff0..de63f6b 100644 --- a/src/App.js +++ b/src/App.js @@ -11,7 +11,7 @@ import 'highlight.js/styles/github-gist.css'; import { Container, Row, Column } from './skeleton'; -import { Articles, RoutedArticle } from './Article'; +import { Articles, FullArticle } from './Article'; import { Footer } from './Footer'; import { Header } from './Header'; import { NavList, TagNav, HistoryNav } from './Nav'; @@ -38,10 +38,10 @@ class App extends Component { { /* Article routes */ } - + { /* 404 fallback */ } - + @@ -82,7 +82,7 @@ class About extends Component { } } -class FourOhFour extends Component { +class NotFound extends Component { render () { return (
diff --git a/src/Article.js b/src/Article.js index 153fb5b..4e41bc4 100644 --- a/src/Article.js +++ b/src/Article.js @@ -1,30 +1,52 @@ import React, { Component } from 'react'; import Icon from 'react-fontawesome'; import Markdown from 'react-markdown'; +import { Link } from 'react-router-dom'; +import slugify from 'slugify'; import { ListLink } from './Nav'; class Article extends Component { render() { - let postLink = ""; + let body = ""; + let readMore = ""; + if (this.props.blurb) { + body = this.props.article.blurb; + readMore = (read more); + } else { + body = this.props.article.body; + } return ( ); } + postLink() { + let date = new Date(this.props.article.date); + let year = date.getUTCFullYear(); + let month = date.getUTCMonth() + 1; + + let slug = this.props.article.slug; + if (!slug) { + slug = slugify(this.props.article.title); + } + + return `/${year}/${month}/${slug}`; + } + meta() { // TODO: Fill this in with real metadata. // Also should this be hidden for pages? That will require some CSS tweaks @@ -35,7 +57,7 @@ class Article extends Component { return (
- +
    @@ -63,29 +85,67 @@ class Article extends Component { } } -// Goofball article for routing testing -class RoutedArticle extends Component { + +class FullArticle extends Component { constructor(props) { super(props); this.props = props; this.params = props.match.params; this.state = { - body: '', - title: 'default title', - date: 'default date', - tags: [], + article: null } } + fetchArticle() { + fetch('/site.json') + .then((resp) => resp.json()) + .then((blob) => { + let found = false; + for (let post of blob.posts) { + let slug = post.slug; + if (!slug) { + slug = slugify(post.title); + } + + console.log('title compare:', slug, this.params.slug); + if (slug === this.params.slug) { + this.setState({article: post}) + found = true; + } + } + + if (!found) { + console.log('article not found'); + /* TODO: return 404 */ + } + }); + } + + componentDidMount() { + this.fetchArticle(); + } + + componentWillReceiveProps(props) { + this.params = props.match.params; + this.fetchArticle(); + } + render() { - return ( -
    - ) + if (this.state.article) { + return ( +
    + ) + } else { + return ( +

    Loading...

    + ) + } } } - class Articles extends Component { constructor(props) { super(props); @@ -115,9 +175,6 @@ class Articles extends Component { let posts = blob.posts.slice(offset, offset + this.per_page); this.setState({articles: posts}); - }) - .catch(function(error) { - console.log("Oh no! " + error); }); } @@ -131,18 +188,22 @@ class Articles extends Component { } render() { - return ( -
    - {this.state.articles.map(article => -
    - )} -
    - ) + if (this.state.articles.length > 0) { + return ( +
    + {this.state.articles.map(article => +
    + )} +
    + ) + } else { + return

    Loading...

    + } } } -export { Article, Articles, RoutedArticle }; +export { Article, FullArticle, Articles };