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
import React, { Component } from 'react'
import { MdSearch } from 'react-icons/lib/md'
import Payments from './components/Payments'
import Invoices from './components/Invoices'
import styles from './Activity.scss'
class Activity extends Component {
constructor(props, context) {
super(props, context)
this.state = {
tab: 2
}
}
componentWillMount() {
this.props.fetchActivity()
}
render() {
const { tab } = this.state
const { activity: { isLoading, payments, invoices } } = this.props
if (isLoading) { return <div>Loading...</div> }
return (
<div>
@ -20,29 +31,28 @@ class Activity extends Component {
<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.activities}>
<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}>
<ul className={styles.activityList}>
{
payments.map((payment, index) => {
console.log('payment: ', payment)
return (
<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>
{
tab === 1 ?
<Payments payments={payments} />
:
<Invoices invoices={invoices} />
}
</div>
</div>
</div>

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

@ -28,19 +28,35 @@
}
}
.transactions {
.activities {
background: #F7F7F7;
.header {
width: 75%;
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;
.title {
display: inline-block;
margin: 60px 0 20px 0;
padding: 5px 10px;
background: #F7F7F7;
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;
padding: 20px 0;
.activityList {
width: 75%;
margin: 0 auto;
background: #fff;
}
}
.activityList {
width: 75%;
margin: 0 auto;
background: #fff;
}
.activity {
padding: 35px 10px;
border-bottom: 1px solid #f2f2f2;
font-size: 14px;
.left, .center, .right {
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 {
width: 85%;
position: relative;
width: 80%;
height: 100vh;
display: inline-block;
vertical-align: top;

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

@ -1,7 +1,7 @@
.nav {
display: inline-block;
vertical-align: top;
width: 15%;
width: 20%;
font-size: 24px;
background: #1d1d1d;
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": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz",
"integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=",
"dev": true
"integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg="
},
"binary": {
"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": {
"version": "2.0.0",
"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",
"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": {
"version": "3.0.0-alpha.1",
"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": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",

4
package.json

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

Loading…
Cancel
Save