Browse Source

feature(activity styles): add invoices and improve activity design

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
3011322962
  1. 54
      app/routes/activity/components/Activity.js
  2. 46
      app/routes/activity/components/Activity.scss
  3. 45
      app/routes/activity/components/components/Invoices.js
  4. 42
      app/routes/activity/components/components/Invoices.scss
  5. 53
      app/routes/activity/components/components/Payments.js
  6. 37
      app/routes/activity/components/components/Payments.scss
  7. 3
      app/routes/app/components/App.scss
  8. 2
      app/routes/app/components/components/Nav.scss
  9. 23
      app/utils/bitcoin.js
  10. 29
      package-lock.json
  11. 4
      package.json

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

@ -1,15 +1,26 @@
// @flow // @flow
import React, { Component } from 'react' import React, { Component } from 'react'
import { MdSearch } from 'react-icons/lib/md' import { MdSearch } from 'react-icons/lib/md'
import Payments from './components/Payments'
import Invoices from './components/Invoices'
import styles from './Activity.scss' import styles from './Activity.scss'
class Activity extends Component { class Activity extends Component {
constructor(props, context) {
super(props, context)
this.state = {
tab: 2
}
}
componentWillMount() { componentWillMount() {
this.props.fetchActivity() this.props.fetchActivity()
} }
render() { render() {
const { tab } = this.state
const { activity: { isLoading, payments, invoices } } = this.props const { activity: { isLoading, payments, invoices } } = this.props
if (isLoading) { return <div>Loading...</div> } if (isLoading) { return <div>Loading...</div> }
return ( return (
<div> <div>
@ -20,29 +31,28 @@ class Activity extends Component {
<input className={`${styles.text} ${styles.input}`} placeholder='Search transactions by amount, pubkey, channel' type='text' /> <input className={`${styles.text} ${styles.input}`} placeholder='Search transactions by amount, pubkey, channel' type='text' />
</div> </div>
<div className={styles.transactions}> <div className={styles.activities}>
<h2 className={styles.header}>Payments</h2> <header className={styles.header}>
<span
className={`${styles.title} ${tab === 1 ? styles.active : null}`}
onClick={() => this.setState({ tab: 1 })}
>
Payments
</span>
<span
className={`${styles.title} ${tab === 2 ? styles.active : null}`}
onClick={() => this.setState({ tab: 2 })}
>
Invoices
</span>
</header>
<div className={styles.activityContainer}> <div className={styles.activityContainer}>
<ul className={styles.activityList}> {
{ tab === 1 ?
payments.map((payment, index) => { <Payments payments={payments} />
console.log('payment: ', payment) :
return ( <Invoices invoices={invoices} />
<li key={index} className={styles.activity}> }
<div className={styles.left}>
<div className={styles.path}>{payment.path[0]}</div>
</div>
<div className={styles.center}>
<div className={styles.date}>{payment.creation_date}</div>
</div>
<div className={styles.right}>
<span className={styles.value}>{payment.value}</span>
</div>
</li>
)
})
}
</ul>
</div> </div>
</div> </div>
</div> </div>

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

@ -28,19 +28,35 @@
} }
} }
.transactions { .activities {
background: #F7F7F7; background: #F7F7F7;
.header { .header {
width: 75%; width: 75%;
margin: 0 auto; margin: 0 auto;
padding: 60px 0 20px 0;
background: #F7F7F7; .title {
color: #999; display: inline-block;
text-transform: uppercase; margin: 60px 0 20px 0;
font-size: 14px; padding: 5px 10px;
font-weight: 400; background: #F7F7F7;
letter-spacing: 1.6px; color: #999;
text-transform: uppercase;
font-size: 14px;
font-weight: 400;
letter-spacing: 1.6px;
cursor: pointer;
transition: all 0.5s;
&:first-child {
border-right: 1px solid #999;
}
&.active {
color: #eec27b;
}
}
} }
} }
@ -48,16 +64,18 @@
background: #fff; background: #fff;
padding: 20px 0; padding: 20px 0;
.activityList { }
width: 75%;
margin: 0 auto; .activityList {
background: #fff; width: 75%;
} margin: 0 auto;
background: #fff;
} }
.activity { .activity {
padding: 35px 10px; padding: 35px 10px;
border-bottom: 1px solid #f2f2f2; border-bottom: 1px solid #f2f2f2;
font-size: 14px;
.left, .center, .right { .left, .center, .right {
display: inline-block; display: inline-block;

45
app/routes/activity/components/components/Invoices.js

@ -0,0 +1,45 @@
// @flow
import React, { Component } from 'react'
import Moment from 'react-moment'
import 'moment-timezone'
import { satoshisToBtc } from '../../../../utils/bitcoin'
import styles from './Invoices.scss'
class Invoices extends Component {
render() {
const { invoices } = this.props
return (
<ul className={styles.invoices}>
<li className={styles.invoiceTitles}>
<div className={styles.left}>
<div>Payment Request</div>
</div>
<div className={styles.center}>
<div>Memo</div>
</div>
<div className={styles.right}>
<div>Amount</div>
</div>
</li>
{
invoices.map((invoice, index) => (
<li key={index} className={styles.invoice}>
<div className={styles.left}>
<div className={styles.path}>{invoice.payment_request}</div>
</div>
<div className={styles.center}>
<div>{invoice.memo}</div>
</div>
<div className={styles.right}>
<div className={invoice.settled ? styles.settled : null}>{satoshisToBtc(invoice.value, 2500)}</div>
</div>
</li>
)
)
}
</ul>
)
}
}
export default Invoices

42
app/routes/activity/components/components/Invoices.scss

@ -0,0 +1,42 @@
.invoices {
width: 75%;
margin: 0 auto;
background: #fff;
}
.invoice, .invoiceTitles {
display: flex;
flex-direction: 'row';
padding: 35px 10px;
border-bottom: 1px solid #f2f2f2;
font-size: 14px;
.left {
flex: 7;
font-size: 12px;
}
.center {
flex: 2;
}
.right {
flex: 1;
}
.settled {
color: #00c730;
font-weight: bold;
}
}
.invoiceTitles {
border: none;
.left, .center, .right {
color: #000;
text-transform: uppercase;
font-size: 16px;
font-weight: bold;
}
}

53
app/routes/activity/components/components/Payments.js

@ -0,0 +1,53 @@
// @flow
import React, { Component } from 'react'
import Moment from 'react-moment'
import 'moment-timezone'
import { satoshisToBtc } from '../../../../utils/bitcoin'
import styles from './Payments.scss'
class Payments extends Component {
render() {
const { payments } = this.props
return (
<ul className={styles.payments}>
<li className={styles.paymentTitles}>
<div className={styles.left}>
<div>Public Key</div>
</div>
<div className={styles.center}>
<div>Date</div>
</div>
<div className={styles.center}>
<div>Fee</div>
</div>
<div className={styles.right}>
<div>Amount</div>
</div>
</li>
{
payments.map((payment, index) => (
<li key={index} className={styles.payment}>
<div className={styles.left}>
<div className={styles.path}>{payment.path[0]}</div>
</div>
<div className={styles.center}>
<div className={styles.date}>
<Moment format="MMMM Do">{payment.creation_date * 1000}</Moment>
</div>
</div>
<div className={styles.right}>
<span className={styles.fee}>{payment.fee === '0' ? '0' : satoshisToBtc(payment.fee, 2500)}</span>
</div>
<div className={styles.right}>
<span className={styles.value}>{satoshisToBtc(payment.value, 2500)}</span>
</div>
</li>
)
)
}
</ul>
)
}
}
export default Payments

37
app/routes/activity/components/components/Payments.scss

@ -0,0 +1,37 @@
.payments {
width: 75%;
margin: 0 auto;
background: #fff;
}
.payment, .paymentTitles {
display: flex;
flex-direction: 'row';
padding: 35px 10px;
border-bottom: 1px solid #f2f2f2;
font-size: 14px;
.left, .center, .right {
display: inline-block;
vertical-align: top;
}
.center, .right {
flex: 1;
}
.left {
flex: 7;
}
}
.paymentTitles {
border: none;
.left, .center, .right {
color: #000;
text-transform: uppercase;
font-size: 16px;
font-weight: bold;
}
}

3
app/routes/app/components/App.scss

@ -1,5 +1,6 @@
.content { .content {
width: 85%; position: relative;
width: 80%;
height: 100vh; height: 100vh;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;

2
app/routes/app/components/components/Nav.scss

@ -1,7 +1,7 @@
.nav { .nav {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
width: 15%; width: 20%;
font-size: 24px; font-size: 24px;
background: #1d1d1d; background: #1d1d1d;
height: 100vh; height: 100vh;

23
app/utils/bitcoin.js

@ -0,0 +1,23 @@
import sb from 'satoshi-bitcoin'
export function btcToSatoshis(btc) {
if (btc == undefined || btc === '') return
return sb.toSatoshi(btc)
}
export function satoshisToBtc(satoshis) {
if (satoshis == undefined || satoshis === '') return
return sb.toBitcoin(satoshis).toFixed(8)
}
export function satoshisToUsd(satoshis, price) {
if (satoshis == undefined || satoshis === '') return
return btcToUsd(satoshisToBtc(satoshis), price)
}
export function btcToUsd(btc, price) {
return (btc * price).toFixed(2)
}

29
package-lock.json

@ -2133,8 +2133,7 @@
"big.js": { "big.js": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz",
"integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=", "integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg="
"dev": true
}, },
"binary": { "binary": {
"version": "0.3.0", "version": "0.3.0",
@ -10365,6 +10364,19 @@
} }
} }
}, },
"moment": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
"integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
},
"moment-timezone": {
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.13.tgz",
"integrity": "sha1-mc5cfYJyYusPH3AgRBd/YHRde5A=",
"requires": {
"moment": "2.18.1"
}
},
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@ -12296,6 +12308,11 @@
"resolved": "https://registry.npmjs.org/react-inline-svg/-/react-inline-svg-1.1.0.tgz", "resolved": "https://registry.npmjs.org/react-inline-svg/-/react-inline-svg-1.1.0.tgz",
"integrity": "sha1-GWtW9TBA2T0zoNUBMo7zO0InarM=" "integrity": "sha1-GWtW9TBA2T0zoNUBMo7zO0InarM="
}, },
"react-moment": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.6.0.tgz",
"integrity": "sha1-JxNSLQKxjM5ausOLwOMec7q7gQE="
},
"react-proxy": { "react-proxy": {
"version": "3.0.0-alpha.1", "version": "3.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz", "resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz",
@ -13148,6 +13165,14 @@
} }
} }
}, },
"satoshi-bitcoin": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/satoshi-bitcoin/-/satoshi-bitcoin-1.0.4.tgz",
"integrity": "sha1-0AK2dwddXLvywhGo3zJUvN9QseQ=",
"requires": {
"big.js": "3.1.3"
}
},
"sax": { "sax": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",

4
package.json

@ -183,15 +183,18 @@
}, },
"dependencies": { "dependencies": {
"axios": "^0.16.2", "axios": "^0.16.2",
"big.js": "^3.1.3",
"devtron": "^1.4.0", "devtron": "^1.4.0",
"electron-debug": "^1.2.0", "electron-debug": "^1.2.0",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"history": "^4.6.3", "history": "^4.6.3",
"moment-timezone": "^0.5.13",
"react": "^15.6.1", "react": "^15.6.1",
"react-dom": "^15.6.1", "react-dom": "^15.6.1",
"react-hot-loader": "3.0.0-beta.6", "react-hot-loader": "3.0.0-beta.6",
"react-icons": "^2.2.5", "react-icons": "^2.2.5",
"react-inline-svg": "^1.1.0", "react-inline-svg": "^1.1.0",
"react-moment": "^0.6.0",
"react-redux": "^5.0.5", "react-redux": "^5.0.5",
"react-router": "^4.1.1", "react-router": "^4.1.1",
"react-router-dom": "^4.1.1", "react-router-dom": "^4.1.1",
@ -199,6 +202,7 @@
"react-svg": "^2.1.21", "react-svg": "^2.1.21",
"redux": "^3.7.1", "redux": "^3.7.1",
"redux-thunk": "^2.2.0", "redux-thunk": "^2.2.0",
"satoshi-bitcoin": "^1.0.4",
"source-map-support": "^0.4.15" "source-map-support": "^0.4.15"
}, },
"devEngines": { "devEngines": {

Loading…
Cancel
Save