Add API models, mock backend, more tests

This commit is contained in:
Jan Tuomi
2018-06-20 14:51:12 +03:00
parent 4ba5b368a6
commit 9e2403ba8a
15 changed files with 686 additions and 1923 deletions
+41 -5
View File
@@ -1,28 +1,64 @@
import * as React from "react";
import { observer } from "mobx-react";
import "./App.scss";
import appState from "../../stores/AppStore";
import appStore from "../../stores/AppStore";
import Button from "../Button";
import { getPosts, Post as PostInterface } from "../../models/post";
import Post from "../Post";
export interface AppProps {
appState: {
appStore: {
increment: () => string,
counter: number
};
}
@observer class App extends React.Component<AppProps, undefined> {
export interface AppState {
posts: PostInterface[];
error: string | Error;
}
@observer class App extends React.Component<AppProps, AppState> {
constructor(props) {
super(props);
this.fetchPosts = this.fetchPosts.bind(this);
this.state = {
error: "",
posts: [],
};
this.fetchPosts();
}
async fetchPosts() {
try {
const posts = await getPosts();
this.setState({
posts,
});
} catch (err) {
this.setState({
error: "Failed to get posts! Is the mock backend on?",
});
}
}
render() {
return <div className="app__landing">
<h1>Aalto-yliopiston sähköinsinöörikilta!</h1>
<p>Sähköä, viinaa, naisia.</p>
<Button onClick={this.props.appState.increment}>{this.props.appState.counter}</Button>
<div className="app__landing__container--button">
<h2>Increment button (MobX)</h2>
<Button onClick={this.props.appStore.increment}>{this.props.appStore.counter}</Button>
</div>
<div className="app__landing__container--posts">
<h2>Posts from mock server</h2>
{ this.state.posts.map((post, index) => <Post key={index} post={post} />)}
</div>
<div className="app__landing__container--error">
{ this.state.error }
</div>
</div>;
}
}
export default props => <App appState={appState} {...props} />;
export default props => <App appStore={appStore} {...props} />;
+1
View File
@@ -11,6 +11,7 @@
&:hover {
border: 2px solid $dark-blue;
cursor: pointer;
}
&:active,
+6
View File
@@ -0,0 +1,6 @@
.post {
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
+20
View File
@@ -0,0 +1,20 @@
import * as React from "react";
import "./Post.scss";
import { Post as PostInterface } from "../../models/posts";
export interface PostProps {
post: PostInterface;
}
class Post extends React.Component<PostProps, undefined> {
render() {
const { title, author, id } = this.props.post;
return (
<div className="post">
#{ id }: <strong>{ title }</strong> from <i>{ author }</i>
</div>
);
}
}
export default Post;
+2
View File
@@ -0,0 +1,2 @@
import Post from "./Post";
export default Post;
+1
View File
@@ -2,6 +2,7 @@ import * as React from "react";
import {render} from "react-dom";
import {AppContainer} from "react-hot-loader";
import App from "./components/App";
import "normalize.css";
import "./index.scss";
const rootEl = document.getElementById("root");
+19
View File
@@ -0,0 +1,19 @@
import axios from "axios";
const url = `${process.env.API_URL}/posts`;
export interface Post {
id: number;
title: string;
author: string;
}
export async function getPosts(): Promise<Post[]> {
try {
const resp = await axios.get(url);
return resp.data;
} catch (err) {
console.error(err);
throw err;
}
}