diff --git a/.babelrc b/.babelrc
index 4ffef06..274617b 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,3 +1,4 @@
{
- "presets": ["env", "react"]
+ "presets": ["env", "react"],
+ "plugins": ["transform-object-rest-spread"]
}
diff --git a/package.json b/package.json
index f09dd4d..c618d17 100644
--- a/package.json
+++ b/package.json
@@ -13,11 +13,13 @@
},
"dependencies": {
"react": "^16.3.1",
- "react-dom": "^16.3.1"
+ "react-dom": "^16.3.1",
+ "react-router-dom": "^5.2.0"
},
"devDependencies": {
"babel-core": "6.26.*",
"babel-loader": "7.1.*",
+ "babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "1.7.0",
"babel-preset-react": "6.24.*",
"css-loader": "2.1.*",
diff --git a/src/ActivityDetails.jsx b/src/ActivityDetails.jsx
new file mode 100644
index 0000000..d939dc6
--- /dev/null
+++ b/src/ActivityDetails.jsx
@@ -0,0 +1,42 @@
+import React, {Component, Fragment} from 'react';
+import ReactDOM from 'react-dom';
+
+import ActivityItem from './ActivityItem.jsx';
+import { Link } from 'react-router-dom';
+
+export default class ActivityDetails extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {details: null};
+
+ this.fetchDetails(this.props.id);
+ }
+
+ fetchDetails(id) {
+ fetch(`https://aircall-job.herokuapp.com/activities/${id}`)
+ .then((data) => {
+ data.json().then((result) => {
+ this.setState({...this.state, details:result});
+ });
+ });
+ }
+
+ render () {
+ console.log('render', this.props);
+ if (this.state.details === null) return '';
+ return (
+
+
+
From: {this.state.details.from}
+
To: {this.state.details.from}
+
Via: {this.state.details.via}
+
Duration: {this.state.details.duration}s
+
+
+ < Back
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/ActivityItem.jsx b/src/ActivityItem.jsx
new file mode 100644
index 0000000..6b91776
--- /dev/null
+++ b/src/ActivityItem.jsx
@@ -0,0 +1,56 @@
+import React, {Component, Fragment} from 'react';
+import ReactDOM from 'react-dom';
+import { Link } from 'react-router-dom';
+
+export default class ActivityItem extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ archive(id) {
+ window.updateActivity(id, true);
+ }
+
+ click(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ this.archive(this.props.activity.id);
+ }
+
+ renderInbound() {
+ return (
+
+
+ INBOUND
+ from: {this.props.activity.from}
+ to: {this.props.activity.to != null ? this.props.activity.to : "(Unknown)"}
+ via: {this.props.activity.via}
+
+
+
+ )
+ }
+
+ renderOutbound() {
+ return (
+
+
+ OUTBOUND
+ from: {this.props.activity.from}
+ to: {this.props.activity.to != null ? this.props.activity.to : "(Unknown)"}
+ via: {this.props.activity.via}
+
+
+
+ )
+ }
+
+ render () {
+ return (
+
+
+ {this.props.activity.direction === "inbound" ? this.renderInbound(): this.renderOutbound()}
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/ActivityList.jsx b/src/ActivityList.jsx
new file mode 100644
index 0000000..7030788
--- /dev/null
+++ b/src/ActivityList.jsx
@@ -0,0 +1,24 @@
+import React, {Component} from 'react';
+import ReactDOM from 'react-dom';
+
+import ActivityItem from './ActivityItem.jsx';
+
+export default class ActivityList extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render () {
+ console.log('render', this.props);
+ return (
+
+
+ {this.props.activities.map((activity) =>
+ activity.is_archived ? null :
+ )}
+
+ Loading : {this.props.fetching? 'yes': 'no'}
+
+ );z
+ }
+}
\ No newline at end of file
diff --git a/src/App.jsx b/src/App.jsx
index 6f44e55..8d98e89 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,17 +1,80 @@
-import React from 'react';
+import React, { Component } from 'react';
+import { BrowserRouter, Switch, Route } from 'react-router-dom'
import ReactDOM from 'react-dom';
import Header from './Header.jsx';
+import ActivityList from './ActivityList.jsx';
+import ActivityDetails from './ActivityDetails.jsx';
-const App = () => {
- return (
-
-
-
Some activities should be here
-
- );
+class App extends Component {
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ fetching: false,
+ activities: []
+ };
+
+ window.fetchState = this.fetchState.bind(this);
+ window.updateActivity = this.updateActivity.bind(this);
+ }
+
+ componentDidMount() {
+ this.fetchState();
+ }
+
+ updateActivity(id, archive) {
+ this.setState({...this.state, fetching: true});
+ fetch(`https://aircall-job.herokuapp.com/activities/${id}`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ mode: 'cors',
+ body: JSON.stringify({is_archived: archive})
+ }).then((data) => {
+ data.json().then((updatedActivity) => {
+ var newList = this.replaceActivity(updatedActivity);
+ this.setState({...this.state, fetching: false, activities: newList});
+ });
+ });
+ }
+
+ replaceActivity(newActivity) {
+ return this.state.activities.map((currentEntry) => {
+ if (currentEntry.id === newActivity.id) return newActivity;
+ return currentEntry;
+ })
+ }
+
+
+
+ fetchState() {
+ console.log('load');
+ this.setState({...this.state, fetching: true});
+ fetch('https://aircall-job.herokuapp.com/activities').then((response) => {
+ response.json().then((result) => {
+ console.log(result);
+ this.setState({...this.state, fetching: false, activities: result});
+ })
+ });
+ }
+
+ render() {
+ return (
+
+ );
+ }
};
-ReactDOM.render(, document.getElementById('app'));
+ReactDOM.render(
+, document.getElementById('app'));
export default App;
diff --git a/src/Header.jsx b/src/Header.jsx
index 46cbb90..502f144 100644
--- a/src/Header.jsx
+++ b/src/Header.jsx
@@ -1,8 +1,9 @@
import React from 'react';
-const Header = () => {
+const Header = (props) => {
return (
+ {props.fetching ? "Loading..." : ""}