Browse Source

feature(activity reducer): add activity reducer and api calls

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
cb7dbea74c
  1. 34
      app/api/index.js
  2. 52
      app/reducers/activity.js
  3. 4
      app/reducers/index.js
  4. 4
      app/routes.js
  5. 46
      app/routes/activity/components/Activity.js
  6. 27
      app/routes/activity/components/Activity.scss
  7. 13
      app/routes/activity/containers/ActivityContainer.js
  8. 3
      app/routes/activity/index.js
  9. 22
      app/routes/home/components/Home.js
  10. 8
      app/routes/home/containers/HomeContainer.js
  11. 3
      app/routes/home/index.js
  12. 22
      package-lock.json
  13. 1
      package.json

34
app/api/index.js

@ -0,0 +1,34 @@
import axios from 'axios'
export function callApi(endpoint, method = 'get', data = null) {
const BASE_URL = 'http://localhost:3000/api/'
let payload
if (data) {
payload = {
headers: {
'Content-Type': 'application/json'
},
method,
data,
url: `${BASE_URL}${endpoint}`
}
} else {
payload = {
headers: {
'Content-Type': 'application/json'
},
method,
url: `${BASE_URL}${endpoint}`
}
}
return axios(payload)
.then(response => response.data)
.catch(error => error)
}
export function callApis(endpoints) {
const BASE_URL = 'http://localhost:3000/api/'
return axios.all(endpoints.map(endpoint => callApi(endpoint)))
}

52
app/reducers/activity.js

@ -0,0 +1,52 @@
import { callApis } from '../api'
// ------------------------------------
// Constants
// ------------------------------------
export const GET_ACTIVITY = 'GET_ACTIVITY'
export const RECEIVE_ACTIVITY = 'RECEIVE_ACTIVITY'
// ------------------------------------
// Actions
// ------------------------------------
export function getActivity() {
return {
type: GET_ACTIVITY
}
}
export function receiveActvity(data) {
return {
type: RECEIVE_ACTIVITY,
payments: data[0].data.payments,
invoices: data[1].data.invoices
}
}
export const fetchActivity = () => async (dispatch) => {
dispatch(getActivity())
const activity = await callApis(['payments', 'invoices'])
dispatch(receiveActvity(activity))
}
// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[GET_ACTIVITY]: (state) => ({ ...state, isLoading: true }),
[RECEIVE_ACTIVITY]: (state, { payments, invoices }) => ({ ...state, isLoading: false, payments, invoices })
}
// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
isLoading: false,
payments: [],
invoices: []
}
export default function activityReducer(state = initialState, action) {
const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state
}

4
app/reducers/index.js

@ -1,9 +1,11 @@
// @flow
import { combineReducers } from 'redux'
import { routerReducer as router } from 'react-router-redux'
import activity from './activity'
const rootReducer = combineReducers({
router
router,
activity
})
export default rootReducer

4
app/routes.js

@ -2,12 +2,12 @@
import React from 'react'
import { Switch, Route } from 'react-router'
import App from './routes/app'
import Home from './routes/home'
import Activity from './routes/activity'
export default () => (
<App>
<Switch>
<Route path='/' component={Home} />
<Route path='/' component={Activity} />
</Switch>
</App>
);

46
app/routes/activity/components/Activity.js

@ -0,0 +1,46 @@
// @flow
import React, { Component } from 'react'
import { MdSearch } from 'react-icons/lib/md'
import styles from './Activity.scss'
class Activity extends Component {
componentWillMount() {
this.props.fetchActivity()
}
render() {
const { activity: { isLoading, payments, invoices } } = this.props
if (isLoading) { return <div>Loading...</div> }
return (
<div>
<div className={styles.search}>
<label className={`${styles.label} ${styles.input}`}>
<MdSearch />
</label>
<input className={`${styles.text} ${styles.input}`} placeholder='Search transactions by amount, pubkey, channel' type='text' />
</div>
<div className={styles.transactions}>
<h2 className={styles.header}>Payments</h2>
<div className={styles.activityContainer}>
<ul className={styles.activityList}>
{
payments.map((payment, index) => {
console.log('payment: ', payment)
return (
<li key={index} className={styles.activity}>
hi
</li>
)
})
}
</ul>
</div>
</div>
</div>
)
}
}
export default Activity

27
app/routes/home/components/Home.scss → app/routes/activity/components/Activity.scss

@ -27,3 +27,30 @@
font-size: 18px;
}
}
.transactions {
background: #F7F7F7;
.header {
width: 50%;
margin: 0 auto;
padding: 60px 0 20px 0;
background: #F7F7F7;
color: #999;
text-transform: uppercase;
font-size: 14px;
font-weight: 400;
letter-spacing: 1.6px;
}
}
.activityContainer {
background: #fff;
padding: 20px 0;
.activityList {
width: 50%;
margin: 0 auto;
background: #fff;
}
}

13
app/routes/activity/containers/ActivityContainer.js

@ -0,0 +1,13 @@
import { connect } from 'react-redux'
import { fetchActivity } from '../../../reducers/activity'
import Activity from '../components/Activity'
const mapDispatchToProps = {
fetchActivity
}
const mapStateToProps = (state) => ({
activity: state.activity
})
export default connect(mapStateToProps, mapDispatchToProps)(Activity)

3
app/routes/activity/index.js

@ -0,0 +1,3 @@
import ActivityContainer from './containers/ActivityContainer'
export default ActivityContainer

22
app/routes/home/components/Home.js

@ -1,22 +0,0 @@
// @flow
import React, { Component } from 'react'
import { MdSearch } from 'react-icons/lib/md'
import styles from './Home.scss'
class Home extends Component {
render() {
return (
<div>
<div className={styles.search}>
<label className={`${styles.label} ${styles.input}`}>
<MdSearch />
</label>
<input className={`${styles.text} ${styles.input}`} placeholder='Search transactions by amount, pubkey, channel' type='text' />
</div>
</div>
)
}
}
export default Home

8
app/routes/home/containers/HomeContainer.js

@ -1,8 +0,0 @@
import { connect } from 'react-redux'
import Home from '../components/Home'
const mapDispatchToProps = {}
const mapStateToProps = (state) => ({})
export default connect(mapStateToProps, mapDispatchToProps)(Home)

3
app/routes/home/index.js

@ -1,3 +0,0 @@
import HomeContainer from './containers/HomeContainer'
export default HomeContainer

22
package-lock.json

@ -622,6 +622,25 @@
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
"dev": true
},
"axios": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.16.2.tgz",
"integrity": "sha1-uk+S8XFn37q0CYN4VFS5rBScPG0=",
"requires": {
"follow-redirects": "1.2.4",
"is-buffer": "1.1.5"
},
"dependencies": {
"follow-redirects": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.4.tgz",
"integrity": "sha512-Suw6KewLV2hReSyEOeql+UUkBVyiBm3ok1VPrVFRZnQInWpdoZbbiG5i8aJVSjTr0yQ4Ava0Sh6/joCg1Brdqw==",
"requires": {
"debug": "2.6.8"
}
}
}
},
"axobject-query": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
@ -8210,8 +8229,7 @@
"is-buffer": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
"dev": true
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
},
"is-builtin-module": {
"version": "1.0.0",

1
package.json

@ -182,6 +182,7 @@
"webpack-merge": "^4.1.0"
},
"dependencies": {
"axios": "^0.16.2",
"devtron": "^1.4.0",
"electron-debug": "^1.2.0",
"font-awesome": "^4.7.0",

Loading…
Cancel
Save