Permalink
Browse files

πŸŽ‰ examples/react-app-blog: a sweet starter to discover phenomic with …

…react and make a blog in a few minutes
  • Loading branch information...
MoOx committed Apr 1, 2018
1 parent 9981ed5 commit 4e52d7c409c422d01856af24b9845c2cb4ee621c
Showing with 1,081 additions and 2 deletions.
  1. +26 βˆ’0 examples/react-app-blog/App.js
  2. +30 βˆ’0 examples/react-app-blog/Html.js
  3. +16 βˆ’0 examples/react-app-blog/README.md
  4. +46 βˆ’0 examples/react-app-blog/__tests__/__snapshots__/index.js.snap
  5. +39 βˆ’0 examples/react-app-blog/__tests__/index.js
  6. +30 βˆ’0 examples/react-app-blog/content/pages/about.md
  7. +28 βˆ’0 examples/react-app-blog/content/pages/index.md
  8. +15 βˆ’0 examples/react-app-blog/content/posts/fifth-post.md
  9. +30 βˆ’0 examples/react-app-blog/content/posts/first-post.md
  10. +6 βˆ’0 examples/react-app-blog/content/posts/fourth-post.md
  11. +6 βˆ’0 examples/react-app-blog/content/posts/second-post.md
  12. +6 βˆ’0 examples/react-app-blog/content/posts/third-post.md
  13. +27 βˆ’0 examples/react-app-blog/package.json
  14. BIN examples/react-app-blog/preview.jpg
  15. BIN examples/react-app-blog/public/favicon.ico
  16. +2 βˆ’0 examples/react-app-blog/public/robots.txt
  17. +71 βˆ’0 examples/react-app-blog/src/ActivityIndicator.js
  18. +58 βˆ’0 examples/react-app-blog/src/Footer.js
  19. +162 βˆ’0 examples/react-app-blog/src/Header.js
  20. +93 βˆ’0 examples/react-app-blog/src/LatestPosts.js
  21. +93 βˆ’0 examples/react-app-blog/src/Layout.js
  22. +63 βˆ’0 examples/react-app-blog/src/Page.js
  23. +45 βˆ’0 examples/react-app-blog/src/PageBlog.js
  24. +25 βˆ’0 examples/react-app-blog/src/PageBlogPost.js
  25. +61 βˆ’0 examples/react-app-blog/src/PageError.js
  26. +31 βˆ’0 examples/react-app-blog/src/PostLayoutDefault.js
  27. +31 βˆ’0 examples/react-app-blog/src/PostLayoutNoHero.js
  28. +1 βˆ’1 examples/react-app-getting-started/Html.js
  29. +1 βˆ’1 examples/react-app-getting-started/package.json
  30. +39 βˆ’0 flow-typed/npm/react-topbar-progress-indicator_vx.x.x.js
@@ -0,0 +1,26 @@
import * as React from "react";
import { Router, Route, browserHistory } from "react-router";
import { createApp, renderApp } from "@phenomic/preset-react-app/lib/client";
import Page from "./src/Page";
import PageBlog from "./src/PageBlog";
import PageBlogPost from "./src/PageBlogPost";
import PageError from "./src/PageError";
const routes = () => (
<Router history={browserHistory}>
<Route path="/" component={Page} />
<Route path="/blog/" component={PageBlog} />
<Route path="/blog/after/:after" component={PageBlog} />
<Route path="/blog/*" component={PageBlogPost} />
{/* for static hosting, we often need an explicit 404.html */}
<Route path="404.html" component={PageError} />
<Route path="*" component={Page} />
</Router>
);
export default createApp(routes);
if (module.hot) {
module.hot.accept(() => renderApp(routes));
}
@@ -0,0 +1,30 @@
import * as React from "react";
import Head from "react-helmet";
export default ({ App, render }: PhenomicHtmlPropsType) => {
// if needed, you can know if you are in development or in static rendering
// const isDev = process.env.PHENOMIC_ENV === "development"
const { Main, State, Script, Style } = render(<App />);
const helmet = Head.renderStatic();
return (
// $FlowFixMe helmet is fine
<html {...helmet.htmlAttributes.toComponent()}>
<head>
{helmet.meta.toComponent()}
{helmet.title.toComponent()}
{helmet.base.toComponent()}
<Style />
{helmet.link.toComponent()}
{helmet.style.toComponent()}
{helmet.script.toComponent()}
{helmet.noscript.toComponent()}
</head>
{/* // $FlowFixMe it works on my machine */}
<body {...helmet.bodyAttributes.toComponent()}>
<Main />
<State />
<Script />
</body>
</html>
);
};
@@ -0,0 +1,16 @@
# Blog with Phenomic + React preset
Simple blog template that includes:
* some pages (home, about, 404.html for static hosting)
* a paginated list of posts
* some articles
* a component to display latest posts
* a loading indicator that is pretty sweet (and only appear when connection is
"slow")
* a way to use different layout from markdown file (via front-matter `layout:
{name}`)
Inspired by the Getting Started guide with a bit of CSS.
![Preview](./preview.jpg)
@@ -0,0 +1,46 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should build example correctly 1`] = `
Array [
"404.html",
"about/index.html",
"blog/after/c2Vjb25kLXBvc3Q=/index.html",
"blog/after/dGhpcmQtcG9zdA==/index.html",
"blog/after/Zm91cnRoLXBvc3Q=/index.html",
"blog/after/ZmlmdGgtcG9zdA==/index.html",
"blog/after/Zmlyc3QtcG9zdA==/index.html",
"blog/fifth-post/index.html",
"blog/first-post/index.html",
"blog/fourth-post/index.html",
"blog/index.html",
"blog/second-post/index.html",
"blog/third-post/index.html",
"index.html",
]
`;
exports[`should build example correctly 2`] = `
Array [
"phenomic/pages/item/.json",
"phenomic/pages/item/about.json",
"phenomic/posts/by-default/1/desc/limit-4.json",
"phenomic/posts/by-default/1/desc/limit-6.json",
"phenomic/posts/by-default/1/desc/limit-6/after-c2Vjb25kLXBvc3Q=.json",
"phenomic/posts/by-default/1/desc/limit-6/after-dGhpcmQtcG9zdA==.json",
"phenomic/posts/by-default/1/desc/limit-6/after-Zm91cnRoLXBvc3Q=.json",
"phenomic/posts/by-default/1/desc/limit-6/after-ZmlmdGgtcG9zdA==.json",
"phenomic/posts/by-default/1/desc/limit-6/after-Zmlyc3QtcG9zdA==.json",
"phenomic/posts/item/fifth-post.json",
"phenomic/posts/item/first-post.json",
"phenomic/posts/item/fourth-post.json",
"phenomic/posts/item/second-post.json",
"phenomic/posts/item/third-post.json",
]
`;
exports[`should build example correctly 3`] = `
Array [
"favicon.ico",
"robots.txt",
]
`;
@@ -0,0 +1,39 @@
/* eslint-disable import/no-extraneous-dependencies */
import globby from "globby";
it("should build example correctly", () => {
const testFolder = __dirname + "/../dist";
const files = globby.sync("**/*", {
cwd: testFolder,
nodir: true,
dot: true
});
// should have html files
const htmlFiles = files.filter(file => file.endsWith(".html"));
expect(htmlFiles).toMatchSnapshot();
const jsonApiFiles = files.filter(
file => file.startsWith("phenomic") && file.endsWith(".json")
);
// should have matching json files
expect(jsonApiFiles).toMatchSnapshot();
// should have assets
const assetsBundlerFiles = files.filter(
file =>
!htmlFiles.includes(file) &&
!jsonApiFiles.includes(file) &&
file.startsWith("phenomic")
);
expect(assetsBundlerFiles.length).toBe(1);
expect(
files.filter(
file =>
!htmlFiles.includes(file) &&
!jsonApiFiles.includes(file) &&
!assetsBundlerFiles.includes(file)
)
).toMatchSnapshot();
});
@@ -0,0 +1,30 @@
---
title: About me
image: https://images.unsplash.com/photo-1495681803763-410ec9ff583d?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ba41fd89a4d5dd9008d04ccea959c072&auto=format&fit=crop&w=900&q=60
---
Ahh. Hey, Doc, we better back up, we don't have enough roads to get up to 88.
Hi. Where were we. In that case, I'll tell you strait out.
Thank you, don't forget to take a flyer. Look, I'm just not ready to ask
Lorraine out to the dance, and not you, nor anybody else on this planet is gonna
make me change my mind. Over there, on my hope chest. I've never seen purple
underwear before, Calvin. What's with the life preserver? Working.
I still don't understand, how am I supposed to go to the dance with her, if
she's already going to the dance with you. Our first television set, Dad just
picked it up today. Do you have a television? I hope so. Uh, look me up when you
get there. Stand tall, boy, have some respect for yourself. Don't you know that
if you let people walk all over you know, they'll be walking all over you for
the rest of your life? Listen to me, do you think I'm gonna spend the rest of my
life in this slop house?
Where were we. That's for messing up my hair. I'm sure that in 1985, plutonium
is available at every corner drug store, but in 1955, it's a little hard to come
by. Marty, I'm sorry, but I'm afraid you're stuck here. Where's Einstein, is he
with you? Listen, this is very important, I forgot my video camera, could you
stop by my place and pick it up on your way to the mall?
Hi. Now Biff, don't con me. Of course I do. Just a second, let's see if I could
find it. George, buddy. remember that girl I introduced you to, Lorraine. What
are you writing? Let's go.
@@ -0,0 +1,28 @@
---
image: https://images.unsplash.com/photo-1495287949939-c5d3daf1cab4?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=8969aebe524921f79c88b9ba605da6c2&auto=format&fit=crop&w=900&q=60
---
Hi there. Here is a good sample for you if you are starting with Phenomic and
React. It provides a simple but powerful codebase that you will be able to
adjust as you wish pretty easily. Be sure to check out the
[source code of this theme](https://github.com/phenomic/phenomic/tree/master/examples/react-app-blog).
Before asking any question about Phenomic, be sure to read the documentation :
* [How to setup a new project with Phenomic](https://phenomic.io/docs/setup/)
* [Getting Started with Phenomic](https://phenomic.io/docs/getting-started/)
* [Usage & APIs](https://phenomic.io/docs/usage/)
* [FAQ](https://phenomic.io/docs/faq/)
Also take a look at
[existing websites that use Phenomic](https://phenomic.io/showcase/), some
projects share their source code!
---
You may want to take a look at the [404.html](/404.html) and tweak the render.
---
_You feel like the base theme is not enough or you just saw something wrong?_
[Please help us make Phenomic better!](https://phenomic.io/contributing/)
@@ -0,0 +1,15 @@
---
title: "I wrote my fifth post and you won't believe what happen next"
date: "2017-01-05"
layout: light
---
This post is using the `light` layout, defined from markdown front-matter. How
cool?
Another post that have a [link to the first one](../first-post/).
An wrong link to [a post that does not exist](../unknown-post/) and another one
to [a page that does not exist](/unknown-page/).
Here is an [external link](http://phenomic.io).
@@ -0,0 +1,30 @@
---
title: "This is a first post"
date: "2017-01-01"
---
# This is a [Markdown](https://en.wikipedia.org/wiki/Markdown#Example) file
If you are new to Markdown, you might want to check those links:
* [What is Markdown?](http://whatismarkdown.com/)
* [Mastering Markdown, a GitHub guide](https://guides.github.com/features/mastering-markdown/)
* [wikipedia.org/wiki/Markdown](https://en.wikipedia.org/wiki/Markdown#Example)
* [masteringmarkdown.com](http://masteringmarkdown.com/)
Code is highlighted by default.
```js
const StatelessComponent = props => {
return (
<div>
Iβ€˜m a stateless component that accepts children
{props.children}
</div>
);
};
// ...
return <StatelessComponent>Example of child</StatelessComponent>;
```
@@ -0,0 +1,6 @@
---
title: "Fourth post, I can't believe I did it"
date: "2017-01-04"
---
Another post
@@ -0,0 +1,6 @@
---
title: "Second post, wow, I did it"
date: "2017-01-02"
---
Another post
@@ -0,0 +1,6 @@
---
title: "A third post means I am really going to write a serious blog"
date: "2017-01-03"
---
Another post
@@ -0,0 +1,27 @@
{
"private": true,
"name": "@phenomic/example-react-app-blog",
"version": "1.0.0-beta.1",
"devDependencies": {
"@phenomic/cli": "^1.0.0-beta.1",
"@phenomic/core": "^1.0.0-beta.1",
"@phenomic/preset-react-app": "^1.0.0-beta.1",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-helmet": "^5.0.0",
"react-router": "^3.2.0"
},
"scripts": {
"start": "phenomic start",
"build": "phenomic build"
},
"phenomic": {
"presets": ["@phenomic/preset-react-app"]
},
"title": "A random blog",
"twitter": "Phenomic_app",
"github": "http://github.com/phenomic/phenomic",
"dependencies": {
"react-topbar-progress-indicator": "^2.0.0"
}
}
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
User-agent: *
Disallow:
@@ -0,0 +1,71 @@
import * as React from "react";
import TopBarProgressIndicator from "react-topbar-progress-indicator";
TopBarProgressIndicator.config({
barThickness: 4,
barColors: {
"0": "#fff",
"1.0": "#fff"
},
shadowBlur: 5
});
class ActivityIndicator extends React.PureComponent<{}, { visible: boolean }> {
state = {
visible: false
};
_timeout: TimeoutID;
componentDidMount() {
this._timeout = setTimeout(() => this.setState({ visible: true }), 250);
}
componentWillUnmount() {
clearTimeout(this._timeout);
}
render() {
return (
<React.Fragment>
<TopBarProgressIndicator />
<style
dangerouslySetInnerHTML={{
__html: `
.ActivityIndicator-loader {
display: flex;
height: 25vh;
justify-content: center;
align-items: center;
}
.ActivityIndicator-spinner {
height: 5vh;
min-height: 5rem;
width: 5vh;
min-width: 5rem;
border: 10px solid rgba(0,0,0,0.2);
border-top-color: rgba(0,0,0,0.8);
border-radius: 100%;
animation: ActivityIndicator-rotation 0.8s infinite linear;
transition: opacity 4s;
}
@keyframes ActivityIndicator-rotation {
from { transform: rotate(0); }
to { transform: rotate(359deg); }
}
`
}}
/>
<div className="ActivityIndicator-loader">
<div
className="ActivityIndicator-spinner"
style={{ opacity: this.state.visible ? 1 : 0 }}
/>
</div>
</React.Fragment>
);
}
}
export default ActivityIndicator;
Oops, something went wrong.

0 comments on commit 4e52d7c

Please sign in to comment.