Add API models, mock backend, more tests
This commit is contained in:
@@ -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} />;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
&:hover {
|
||||
border: 2px solid $dark-blue;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:active,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
.post {
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -0,0 +1,2 @@
|
||||
import Post from "./Post";
|
||||
export default Post;
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user