mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-11 10:22:53 +00:00
too many changes - load posts now
This commit is contained in:
@@ -16,7 +16,7 @@ import Index from './pages/Index';
|
||||
class Main extends React.Component{
|
||||
render(){
|
||||
return(
|
||||
<div>{React.cloneElement(this.props.children, this.props)}</div>
|
||||
<div>{React.cloneElement(this.props.children, this.props)}</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,8 @@ ReactDOM.render((
|
||||
<Router history={history}>
|
||||
<Route path="/" component={App}>
|
||||
<IndexRoute component={Index}/>
|
||||
<Route path="/:page" component={Index}/>
|
||||
<Route path="/:page(/:category)(/:post)" component={Index}/>
|
||||
</Route>
|
||||
</Router>
|
||||
</Provider>
|
||||
),document.getElementById('app'));
|
||||
),document.getElementById('app'));
|
||||
|
||||
@@ -4,9 +4,11 @@ import '../../assets/scss/Footer.scss';
|
||||
|
||||
export default class Footer extends React.Component{
|
||||
|
||||
render(){
|
||||
return(
|
||||
<div class="Footer">Site created and maintained by Mitchell Gerber</div>
|
||||
);
|
||||
}
|
||||
render(){
|
||||
return(
|
||||
<div class="Footer">
|
||||
Site created and maintained by Mitchell Gerber
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
export default class Header extends React.Component{
|
||||
|
||||
render(){
|
||||
return(
|
||||
<header class="Header" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
return(
|
||||
<header class="Header" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
import React from 'react';
|
||||
import marked from 'marked';
|
||||
import highlight from 'highlight.js';
|
||||
|
||||
marked.setOptions({
|
||||
header: true,
|
||||
highlight: (code) => {
|
||||
return highlight.highlightAuto(code).value;
|
||||
}
|
||||
});
|
||||
|
||||
export default class Post extends React.Component{
|
||||
|
||||
|
||||
render(){
|
||||
return(
|
||||
<div></div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
return(
|
||||
<div class="Preview" dangerouslySetInnerHTML={{__html : marked(this.props.content)}}>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
import React from 'react';
|
||||
import Link from 'react-router';
|
||||
import {Link} from 'react-router';
|
||||
|
||||
import '../../assets/scss/Preview.scss';
|
||||
|
||||
export default class Preview extends React.Component{
|
||||
|
||||
insertPosts(posts){
|
||||
let elements = [];
|
||||
for (let i in posts){
|
||||
elements.push(
|
||||
<div class="post" key={i}>
|
||||
<div class="date">{posts[i].date}</div>
|
||||
<div class="intro" dangerouslySetInnerHTML={this.decodeHtml(posts[i].title.toString())}></div>
|
||||
<div dangerouslySetInnerHTML={this.decodeHtml(posts[i].intro.toString())}></div>
|
||||
<p><a class="link" href="#">continue reading...</a></p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return elements;
|
||||
insertPosts(posts){
|
||||
let elements = [];
|
||||
for (let i in posts){
|
||||
elements.push(
|
||||
<div class="post" key={i}>
|
||||
<div class="date">
|
||||
{posts[i].date}
|
||||
</div>
|
||||
<h2 class="intro" >{posts[i].title.toString()}</h2>
|
||||
<p>{posts[i].intro.toString()}</p>
|
||||
<p>
|
||||
<Link class="link" to={`/post/${posts[i].category}/${posts[i].filename}`}>
|
||||
continue reading...
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
decodeHtml(html) {
|
||||
var txt = document.createElement("textarea");
|
||||
txt.innerHTML = html;
|
||||
return {__html : txt.value};
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
render(){
|
||||
const posts = this.props.posts;
|
||||
render(){
|
||||
const posts = this.props.posts;
|
||||
|
||||
return (
|
||||
<div class="Preview">
|
||||
{posts.length > 0 ? this.insertPosts(posts): ""}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div class="Preview">
|
||||
{posts.length > 0 ? this.insertPosts(posts): ""}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,39 +6,61 @@ import '../../assets/scss/Sidebar.scss';
|
||||
|
||||
export default class Sidebar extends React.Component{
|
||||
|
||||
constructor(){
|
||||
super();
|
||||
constructor(){
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
toggler: ""
|
||||
};
|
||||
this.state = {
|
||||
toggler: ""
|
||||
};
|
||||
|
||||
this.onToggle = this.onToggle.bind(this);
|
||||
}
|
||||
this.onToggle = this.onToggle.bind(this);
|
||||
}
|
||||
|
||||
onToggle(){
|
||||
let temp = this.state.toggler;
|
||||
temp = temp === "open" ? "" : "open";
|
||||
onToggle(){
|
||||
let temp = this.state.toggler;
|
||||
temp = temp === "open" ? "" : "open";
|
||||
|
||||
this.setState({
|
||||
toggler: temp
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
toggler: temp
|
||||
});
|
||||
}
|
||||
|
||||
render(){
|
||||
return(
|
||||
<div class={"Sidebar " + this.state.toggler}>
|
||||
<a onClick={this.onToggle} class="toggler"><i class="fa fa-2x fa-navicon" aria-hidden="true" /></a>
|
||||
<h2>About Me</h2>
|
||||
<img src={me}/>
|
||||
<p>My name is Mitchell and I have a passion for software development. I am currently a software engineer and enjoy working on personal projects in my free time.</p>
|
||||
render(){
|
||||
return(
|
||||
<div class={"Sidebar " + this.state.toggler}>
|
||||
<a onClick={this.onToggle} class="toggler">
|
||||
<i
|
||||
class="fa fa-2x fa-navicon"
|
||||
aria-hidden="true" />
|
||||
</a>
|
||||
<h2>
|
||||
About Me
|
||||
</h2>
|
||||
<img src={me}/>
|
||||
<p>
|
||||
My name is Mitchell and I have a passion for software development. I am currently a software engineer and enjoy working on personal projects in my free time.
|
||||
</p>
|
||||
|
||||
<h3>Contact Me</h3>
|
||||
<p><i class="fa fa-envelope" aria-hidden="true"></i><a class="link" href="mailto:mgerb42@gmail.com"> eMail</a></p>
|
||||
<p><i class="fa fa-linkedin-square" aria-hidden="true"></i><a class="link" href="https://www.linkedin.com/in/mitchell-gerber-125391b3" target="_blank"> LinkedIn</a></p>
|
||||
<p><i class="fa fa-github" aria-hidden="true"></i><a class="link" href="https://github.com/mgerb" target="_blank"> GitHub</a></p>
|
||||
<p><i class="fa fa-wpforms" aria-hidden="true"></i><a href="/resume" class="link"> Resume</a></p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
<h3>
|
||||
Contact Me
|
||||
</h3>
|
||||
<p>
|
||||
<i class="fa fa-envelope" aria-hidden="true"></i>
|
||||
<a class="link" href="mailto:mgerb42@gmail.com"> eMail</a>
|
||||
</p>
|
||||
<p>
|
||||
<i class="fa fa-linkedin-square" aria-hidden="true"></i>
|
||||
<a class="link" href="https://www.linkedin.com/in/mitchell-gerber-125391b3" target="_blank"> LinkedIn</a>
|
||||
</p>
|
||||
<p>
|
||||
<i class="fa fa-github" aria-hidden="true"></i>
|
||||
<a class="link" href="https://github.com/mgerb" target="_blank"> GitHub</a>
|
||||
</p>
|
||||
<p>
|
||||
<i class="fa fa-wpforms" aria-hidden="true"> </i>
|
||||
<a href="/resume" class="link"> Resume</a>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,27 +5,46 @@ import Header from '../components/Header';
|
||||
import Preview from '../components/Preview';
|
||||
import Footer from '../components/Footer';
|
||||
import Sidebar from '../components/Sidebar';
|
||||
import Post from '../components/Post';
|
||||
|
||||
//css
|
||||
import '../../assets/css/normalize.css';
|
||||
import '../../assets/scss/main.scss';
|
||||
import 'font-awesome/css/font-awesome.min.css';
|
||||
import '../../assets/css/dracula.css';
|
||||
|
||||
export default class Index extends React.Component{
|
||||
componentDidMount(){
|
||||
export default class Index extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.actions.fetchPreview();
|
||||
this.page = this.props.params.page;
|
||||
this.page === 'post' ? this.props.actions.fetchPost(this.props.params.category, this.props.params.post) : "";
|
||||
}
|
||||
|
||||
render(){
|
||||
return(
|
||||
<div class="Layout">
|
||||
<Header/>
|
||||
<div class="Main">
|
||||
<Preview posts={this.props.redux.preview.posts}/>
|
||||
<Sidebar />
|
||||
</div>
|
||||
<Footer/>
|
||||
|
||||
|
||||
componentWillReceiveProps(nextProps){
|
||||
if(this.props.params !== nextProps.params){
|
||||
const params = nextProps.params;
|
||||
this.page = params.page;
|
||||
|
||||
if(typeof params.post !== 'undefined' && typeof params.category !== 'undefined'){
|
||||
this.props.actions.fetchPost(params.category, params.post);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="Layout" >
|
||||
<Header />
|
||||
<div class="Main">
|
||||
<div class="Content">
|
||||
{typeof this.page === 'undefined' ? <Preview posts={this.props.redux.preview.posts} /> : ""}
|
||||
{this.page === 'post' ? <Post content={this.props.redux.post}/> : ""}
|
||||
</div>
|
||||
);
|
||||
<Sidebar />
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,41 @@
|
||||
import * as types from "./constants";
|
||||
import marked from 'marked';
|
||||
|
||||
function initPreview(posts){
|
||||
return{
|
||||
function initPreview(posts) {
|
||||
return {
|
||||
type: types.INIT_PREVIEW,
|
||||
posts
|
||||
}
|
||||
}
|
||||
|
||||
function loadPost(post){
|
||||
return {
|
||||
type: types.LOAD_POST,
|
||||
post
|
||||
}
|
||||
}
|
||||
|
||||
//using redux-thunk we can modify actions before they get called
|
||||
//in this case we can send the http request here rather in the react component
|
||||
export function fetchPreview(){
|
||||
export function fetchPreview() {
|
||||
return (dispatch) => {
|
||||
return fetch('/public/metadata.json')
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(initPreview(json));
|
||||
dispatch(initPreview(json));
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function fetchPost(category, post) {
|
||||
return (dispatch) => {
|
||||
return fetch(`/public/posts/${category}/${post}.md`)
|
||||
.then(response => response.text())
|
||||
.then(response => {
|
||||
dispatch(loadPost(response));
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//constants
|
||||
export const INIT_PREVIEW = 'INIT_PREVIEW';
|
||||
export const FILTER_PREVIEW = 'FILTER_PREVIEW';
|
||||
export const FILTER_PREVIEW = 'FILTER_PREVIEW';
|
||||
export const LOAD_POST = 'LOAD_POST';
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
//just using one reducer - use combineReducers from redux to modularize things
|
||||
import {combineReducers} from 'redux';
|
||||
import {routerReducer} from 'react-router-redux';
|
||||
import {
|
||||
combineReducers
|
||||
} from 'redux';
|
||||
import {
|
||||
routerReducer
|
||||
} from 'react-router-redux';
|
||||
|
||||
//import typs
|
||||
import * as types from './constants';
|
||||
|
||||
//defaults -
|
||||
//defaults -
|
||||
const defaultState = {
|
||||
preview: {posts: []},
|
||||
filteredPreview: {posts: []}
|
||||
preview: {
|
||||
posts: []
|
||||
},
|
||||
filteredPreview: {
|
||||
posts: []
|
||||
},
|
||||
post: ""
|
||||
};
|
||||
|
||||
//default reducer
|
||||
function reducer(state = defaultState, action){
|
||||
function reducer(state = defaultState, action) {
|
||||
//every reducer gets called when an action is called - we check for the type to modify our state accordingly
|
||||
switch (action.type){
|
||||
switch (action.type) {
|
||||
case types.INIT_PREVIEW:
|
||||
return Object.assign({}, state, {
|
||||
preview: Object.assign({}, state.preview, action.posts)
|
||||
@@ -22,9 +31,14 @@ function reducer(state = defaultState, action){
|
||||
case types.FILTER_PREVIEW:
|
||||
return Object.assign({}, state, {
|
||||
filteredPreview: Object.assign({}, state.filteredPreview, action.posts)
|
||||
});
|
||||
case types.LOAD_POST:
|
||||
return Object.assign({}, state, {
|
||||
post: action.post
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
//return present state if no actions get called
|
||||
return state;
|
||||
}
|
||||
@@ -34,4 +48,4 @@ const allReducers = combineReducers({
|
||||
routing: routerReducer
|
||||
});
|
||||
|
||||
export default allReducers;
|
||||
export default allReducers;
|
||||
|
||||
Reference in New Issue
Block a user