Reimpliment the website design in React

This commit is contained in:
Nick Pegg 2017-09-24 21:23:59 -07:00
parent 833e5f19fc
commit f2244ea3ed
23 changed files with 6351 additions and 47 deletions

View file

@ -1,24 +0,0 @@
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}
.App-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}
.App-intro {
font-size: large;
}
@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

View file

@ -1,21 +1,54 @@
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Container, Row, Column } from './skeleton';
import { Header } from './Header';
import { Footer } from './Footer';
import { NavList, TagNav, HistoryNav } from './Nav';
import { Article } from './Article';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<Header />
<Container>
<Row>
<Column width="two" className="nav">
<NavList />
<TagNav />
</Column>
<Column width="eight">
{ this.articles() }
</Column>
</Row>
<HistoryNav />
</Container>
<Footer />
</div>
);
}
articles() {
// TODO: This is the thing that'll fetch the articles from the JSON blob
// based on the URL that's hit. This will return one or more Articles
return [
<Article
title="This is where a blog post would go"
date="1970-01-01"
/>,
<Article
title="This is another blog post!"
date="1970-01-01"
is_page
/>
];
}
}
export default App;

66
src/Article.js Normal file
View file

@ -0,0 +1,66 @@
import React, { Component } from 'react';
import Icon from 'react-fontawesome';
import Markdown from 'react-markdown';
import { ListLink } from './Nav';
class Article extends Component {
render() {
let postLink = "";
return (
<article>
<header>
<a className="post-title" href={ postLink }>
<h1>{ this.props.title }</h1>
</a>
{ this.meta() }
</header>
<section>
<Markdown source={ this.content() } />
<a href={ postLink }>omg read more</a>
</section>
</article>
);
}
meta() {
// TODO: Fill this in with real metadata.
// Also should this be hidden for pages? That will require some CSS tweaks
let time_text = "Posted"
if (this.props.is_page) {
time_text = "Updated"
}
return (
<div className="post-meta">
<time>{ time_text } { this.props.date }</time>
<div className="post-tags"> <Icon name="tags" />
<ul>
<ListLink name="tag1" href="" />
<ListLink name="tag2" href="" />
</ul>
</div>
</div>
);
}
content () {
/* TODO: Have this return the actual content of the page/post. This should
* probably just be passed in from App.articles()
*
* This is just dummy filler for now to show off the styling of various
* Markdown blocks
*/
return (
"Lorem ipsum `dolor sit amet`, sale fugit ea ius, ut eam alii duis, quaeque salutandi cu mea. His quot doming cu, usu labore antiopam appellantur at, in vidit democritum has. Prompta sententiae duo ut. Nam ne iisque repudiare repudiandae, an mel duis ullum posidonium.\n\n"
+ "# h1 header\n\n"
+ "```\n#!/bin/bash\necho \"This is a code block!\"\n```\n\n"
+ "## h2 header\n\n"
+ "> # Woah\n> Oh and look at this\n>\n> It's a block quote\n\n"
);
}
}
export { Article };

18
src/Footer.js Normal file
View file

@ -0,0 +1,18 @@
import React, { Component } from 'react';
import Icon from 'react-fontawesome';
import { Container } from './skeleton';
class Footer extends Component {
render() {
return (
<div className="page-footer">
<Container>
<Icon name="copyright" /> 2017 Nick Pegg
</Container>
</div>
);
}
}
export { Footer };

17
src/Header.js Normal file
View file

@ -0,0 +1,17 @@
import React, { Component } from 'react';
class Header extends Component {
render() {
return (
<div className="page-header">
<div className="container">
<a href="/">
<h1>nickpegg.com</h1>
</a>
</div>
</div>
);
}
}
export { Header };

75
src/Nav.js Normal file
View file

@ -0,0 +1,75 @@
import React, { Component } from 'react';
import Icon from 'react-fontawesome';
import { Row } from './skeleton';
class ListLink extends Component {
render () {
let icon = null;
if (this.props.icon) {
icon = <Icon name={ this.props.icon } />
}
return (
<li> <a href={ this.props.href }>{ icon } { this.props.name }</a> </li>
);
}
}
class NavList extends Component {
render() {
return (
<Row>
<ul>
<ListLink name="Home" href="/" />
<ListLink name="About" href="/about" />
<ListLink name="Projects" href="/projects" />
<ListLink name="RSS" href="/rss.xml" icon="rss-square" />
</ul>
</Row>
);
}
}
class TagNav extends Component {
render() {
// TODO: Populate these tags from the top tags in the post
let tags = (
<ul>
<ListLink icon="tag" name="Tag 1" href="" />
<ListLink icon="tag" name="Tag 2" href="" />
<ListLink icon="tag" name="Really long tag" href="" />
<ListLink icon="tag" name="Really really really long tag" href="" />
<ListLink icon="tag" name="Another tag" href="" />
</ul>
);
return (
<Row>
<h5 className="nav-header">Top Tags</h5>
{ tags }
</Row>
);
}
}
class HistoryNav extends Component {
render() {
return (
<Row>
<a href="">
<Icon name="arrow-left" />
<span> newer posts</span>
</a>
<a className="u-pull-right" href="">
<span>older posts </span>
<Icon name="arrow-right" />
</a>
</Row>
);
}
}
export { ListLink, NavList, TagNav, HistoryNav };

View file

@ -1,5 +1,132 @@
body {
margin: 0;
padding: 0;
font-family: sans-serif;
background: #FCFCFC;
color: #35352F;
}
a {
color: #FF4F00;
}
a:hover {
color: #FF4F00;
}
h1, h2, h3, h4, h5 {
font-family: 'Quicksand', sans-serif;
}
blockquote {
margin-left: 0;
border-left: 0.5rem solid #dfe2e5;
padding-left: 2rem;
color: #666D70;
}
.page-header {
background: #74E8E2;
margin-bottom: 2rem;
}
.page-header h1 {
margin-bottom: 1rem;
}
.page-header a {
color: inherit;
text-decoration: inherit;
}
/* nav
****************************************/
.nav {
margin-top: 1rem;
}
.nav ul li {
list-style-type: none;
margin-bottom: 0;
}
.nav-header {
margin-bottom: 0;
}
@media (max-width: 999px) {
.nav {
text-align: center;
}
.nav ul li {
display: inline;
}
.nav ul li:first-child::before {
content: "";
}
.nav ul li::before {
content: "|";
}
}
/* articles
****************************************/
article {
margin-bottom: 4rem;
}
.post-title {
color: inherit;
text-decoration: inherit;
}
.post-title h1 {
margin-bottom: 0rem;
}
.post-meta {
color: #757575;
margin-top: 0.5rem;
margin-bottom: 2rem;
}
.post-tags {
display: inline;
margin-left: 1rem;
}
.post-tags * {
display: inline;
}
/* Override this since hljs removes what skeleton sets */
.hljs {
padding: 1rem 1.5rem
}
/* Article headers should go down one size. This is because when you use a
* `#` in Markdown, it outputs a <h1>, but we don't want post headers to be the
* same size as headers elsewhere.
*
* These values were taken from skeleton.css
*/
article section h1 { font-size: 3.6rem; line-height: 1.2; letter-spacing: -.1rem;}
article section h2 { font-size: 3.0rem; line-height: 1.25; letter-spacing: -.1rem; }
article section h3 { font-size: 2.4rem; line-height: 1.3; letter-spacing: -.1rem; }
article section h4 { font-size: 1.8rem; line-height: 1.35; letter-spacing: -.08rem; }
article section h5 { font-size: 1.5rem; line-height: 1.5; letter-spacing: -.05rem; }
/* Larger than phablet */
@media (min-width: 550px) {
article section h1 { font-size: 4.2rem; }
article section h2 { font-size: 3.6rem; }
article section h3 { font-size: 3.0rem; }
article section h4 { font-size: 2.4rem; }
article section h5 { font-size: 1.5rem; }
}
/* footer
****************************************/
.page-footer {
margin-top: 1rem;
margin-bottom: 1rem;
text-align: center;
font-size: smaller;
}

View file

@ -1,8 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import './index.css';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

42
src/skeleton/index.js Normal file
View file

@ -0,0 +1,42 @@
import React, { Component } from 'react';
// Basic Skeleton elements
//
// I should be using one of the many react-skeleton libs that are out there,
// but they're all janky in one way or another. I'll make one work and open a
// PR some day once I have a better grasp of JS, React, and how all the
// packaging exactly works.
class Container extends Component {
render() {
return (
<div className="container">
{this.props.children}
</div>
);
}
}
class Row extends Component {
render() {
return (
<div className="row">
{ this.props.children }
</div>
);
}
}
class Column extends Component {
render() {
return(
<div className={ this.props.width + " columns " + this.props.className }>
{this.props.children}
</div>
);
}
}
export { Container, Row, Column };