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

Commit

Permalink
Add boilerplate from eforms and question viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
meghprkh committed Sep 19, 2017
1 parent 65c8735 commit a5bd639
Show file tree
Hide file tree
Showing 14 changed files with 338 additions and 69 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"dependencies": {
"inferno": "^3.9.0",
"inferno-component": "^3.9.0",
"inferno-scripts": "4.2.0"
"inferno-router": "^3.9.0",
"inferno-scripts": "4.2.0",
"milligram": "^1.3.0"
},
"proxy": "http://localhost:3000",
"scripts": {
Expand Down
22 changes: 0 additions & 22 deletions src/App.css

This file was deleted.

22 changes: 9 additions & 13 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import { version } from 'inferno';
import Component from 'inferno-component';
import './registerServiceWorker';
import Logo from './logo';
import './App.css';

import Navbar from './Navbar';

class App extends Component {
render() {
render({ children }) {
return (
<div className="App">
<div className="App-header">
<Logo width="80" height="80" />
<h2>{`Welcome to Inferno ${version}`}</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
<main className="wrapper">
<Navbar />
<section className="container">
{children}
</section>
</main>
);
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/Login/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Component from 'inferno-component';

class Login extends Component {
state = {
email: ''
}
onChange = e => {
this.setState({ email: e.target.value })
}
onSubmit = e => {
e.preventDefault();
const { email } = this.state;
window.email = email;
window.localStorage.setItem('email', email);
window.browserHistory.push('/')
}
render() {
const { email } = this.state;

return (
<div>
<h1>Login</h1>
<form onSubmit={this.onSubmit}>
<fieldset>
<label>Email</label>
<input type="email" value={email} onChange={this.onChange} name="eforms-email" />
</fieldset>
<button>Submit</button>
</form>
</div>
)
}
}

export default Login;
13 changes: 13 additions & 0 deletions src/Logout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Component from 'inferno-component';

class Logout extends Component {
render() {
window.email = '';
window.localStorage.removeItem('email');
window.browserHistory.push('/')

return <div />
}
}

export default Logout;
17 changes: 17 additions & 0 deletions src/Navbar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import './navbar.css';
import { Link } from 'inferno-router';

export default () => (
<nav className="navigation">
<section className="container">
<Link className="navigation-title" to="/"><h1 className="title">Eforms</h1></Link>
<ul className="navigation-list float-right">
{!window.email ?
<li className="navigation-item"><Link to='/login' className="navigation-link">Login</Link></li>
:
<li className="navigation-item"><Link to='/logout' className="navigation-link">Logout</Link></li>
}
</ul>
</section>
</nav>
)
53 changes: 53 additions & 0 deletions src/Navbar/navbar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.navigation {
background:#f4f5f6;
border-bottom:.1rem solid #d1d1d1;
display:block;
height:5.2rem;
left:0;
max-width:100%;
position:fixed;
right:0;
top:0;
width:100%;
z-index:1
}
.navigation .container {
padding-bottom:0;
padding-top:0
}
.navigation .navigation-list {
list-style:none;
margin-bottom:0;
margin-right:5rem
}
@media (min-width:80rem) {
.navigation .navigation-list {
margin-right:0
}
}
.navigation .navigation-item {
float:left;
margin-bottom:0;
margin-left:2.5rem;
position:relative
}
.navigation .img {
fill:#9b4dca;
height:2rem;
position:relative;
top:.3rem
}
.navigation .navigation-title,.navigation .title {
color:#606c76;
position:relative
}
.navigation .navigation-link,.navigation .navigation-title,.navigation .title {
display:inline;
font-size:1.6rem;
line-height:5.2rem;
padding:0;
text-decoration:none
}
.navigation .navigation-link.active {
color:#606c76
}
33 changes: 33 additions & 0 deletions src/QuestionViewer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* global fetchWithAuth */

import Component from 'inferno-component';

class QuestionViewer extends Component {
state = {
question: {},
loading: true,
error: '',
}
async componentDidMount() {
const { qno } = this.props.params;
var res = await fetchWithAuth(`/questions/${qno}`);
res = await res.json();
if (!res.error) this.setState({ question: res, loading: false })
else this.setState({ error: res.error, loading: false })
}
render() {
const { loading, question, error } = this.state
return (
<div>
{loading && <div>Loading...</div>}
<h1>Q{question.qno}: {question.title}</h1>
<p>
{question.body}
</p>
{error && <div className="error">ERROR: {error}</div>}
</div>
)
}
}

export default QuestionViewer;
41 changes: 41 additions & 0 deletions src/QuestionsList/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* global fetchWithAuth */

import Component from 'inferno-component';
import { Link } from 'inferno-router';

class QuestionsList extends Component {
state = {
questions: [],
loading: true,
error: '',
}
async componentDidMount() {
var res = await fetchWithAuth('/questions');
res = await res.json();
if (!res.error) this.setState({ questions: res, loading: false })
else this.setState({ error: res.error, loading: false })
}
render() {
const { loading, questions, error } = this.state
return (
<div>
{!window.email ?
<ul></ul>
:
<ul className="navigation-title " to="/"><h3 className="float-right">Hello {window.email}</h3></ul>
}
<h1>Questions</h1>
{loading && <div>Loading...</div>}
<ul>
{questions.map(question => (
<li>
<Link to={`/questions/${question.id}/${question.uuid}`}>{question.title}</Link>
</li>))}
</ul>
{error && <div className="error">ERROR: {error}</div>}
</div>
)
}
}

export default QuestionsList;
18 changes: 18 additions & 0 deletions src/fetchWithAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
window.fetchWithAuth = (url, options = {}) => {
url = url.startsWith('/') ? url : '/' + url;
var body = options.body;
if (body && typeof body.getAll !== 'function') { // is not formdata
body = new FormData();
for ( var key in options.body ) {
body.append(key, options.body[key]);
}
}
return fetch(url, {
...options,
body,
headers: {
...options.headers,
email: window.email
}
})
}
22 changes: 18 additions & 4 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
body {
margin: 0;
padding: 0;
font-family: "Open Sans", "lucida grande", "Segoe UI", arial, verdana, "lucida sans unicode", tahoma, sans-serif;
@import "../node_modules/milligram/dist/milligram.min.css";

.wrapper {
display:block;
overflow:hidden;
position:relative;
width:100%
}
.wrapper .container {
max-width:80rem
}
.wrapper>.container {
padding-bottom:7.5rem;
padding-top:7.5rem
}

.error {
color: red;
}
28 changes: 27 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,30 @@ import { render } from 'inferno';
import App from './App';
import './index.css';

render(<App />, document.getElementById('app'));
import { Router, Route, IndexRoute } from 'inferno-router';
import createBrowserHistory from 'history/createBrowserHistory';

import './fetchWithAuth';

import Login from './Login';
import Logout from './Logout';
import QuestionsList from './QuestionsList';
import QuestionViewer from './QuestionViewer';

const browserHistory = createBrowserHistory();
window.browserHistory = browserHistory;

window.email = window.localStorage.getItem('email')

const routes = (
<Router history={ browserHistory }>
<Route component={ App }>
<IndexRoute component={QuestionsList}/>
<Route path="/question/:qno" component={QuestionViewer} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Route>
</Router>
);

render(routes, document.getElementById('app'));
23 changes: 0 additions & 23 deletions src/logo.js

This file was deleted.

Loading

0 comments on commit a5bd639

Please sign in to comment.