Browse Source

feature(channel): styled channel on walle page

renovate/lint-staged-8.x
Jack Mallers 8 years ago
parent
commit
82f76b31ac
  1. 50
      app/reducers/channels.js
  2. 2
      app/reducers/index.js
  3. 4
      app/routes/activity/components/Activity.js
  4. 20
      app/routes/activity/components/components/Invoices.js
  5. 40
      app/routes/activity/components/components/Invoices.scss
  6. 2
      app/routes/app/components/components/Form/Form.js
  7. 2
      app/routes/app/components/components/Form/Form.scss
  8. 85
      app/routes/wallet/components/Wallet.js
  9. 112
      app/routes/wallet/components/Wallet.scss
  10. 15
      app/routes/wallet/containers/WalletContainer.js
  11. 5
      app/variables.scss
  12. 33
      package-lock.json
  13. 2
      package.json

50
app/reducers/channels.js

@ -0,0 +1,50 @@
import { callApi } from '../api'
// ------------------------------------
// Constants
// ------------------------------------
export const GET_CHANNELS = 'GET_CHANNELS'
export const RECEIVE_CHANNELS = 'RECEIVE_CHANNELS'
// ------------------------------------
// Actions
// ------------------------------------
export function getChannels() {
return {
type: GET_CHANNELS
}
}
export function receiveChannels({ channels }) {
return {
type: RECEIVE_CHANNELS,
channels
}
}
export const fetchChannels = () => async (dispatch) => {
dispatch(getChannels())
const channels = await callApi('channels')
dispatch(receiveChannels(channels.data))
}
// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[GET_CHANNELS]: (state) => ({ ...state, channelsLoading: true }),
[RECEIVE_CHANNELS]: (state, { channels }) => ({ ...state, channelsLoading: false, channels })
}
// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
channelsLoading: false,
channels: []
}
export default function channelsReducer(state = initialState, action) {
const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state
}

2
app/reducers/index.js

@ -6,6 +6,7 @@ import info from './info'
import balance from './balance'
import payment from './payment'
import peers from './peers'
import channels from './channels'
import form from './form'
import invoice from './invoice'
import activity from './activity'
@ -17,6 +18,7 @@ const rootReducer = combineReducers({
balance,
payment,
peers,
channels,
form,
invoice,
activity

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

@ -10,7 +10,7 @@ class Activity extends Component {
constructor(props, context) {
super(props, context)
this.state = {
tab: 2
tab: 1
}
}
@ -43,7 +43,7 @@ class Activity extends Component {
<MdSearch />
</label>
<input
value={invoicesSearchText}
value={tab === 1 ? '' : invoicesSearchText}
onChange={event => tab === 1 ? null : searchInvoices(event.target.value)}
className={`${styles.text} ${styles.input}`}
placeholder={tab === 1 ? 'Search transactions by amount, public key, channel' : 'Search requests by memo'}

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

@ -3,6 +3,8 @@ import React, { Component } from 'react'
import Moment from 'react-moment'
import 'moment-timezone'
import { FaBitcoin, FaDollar } from 'react-icons/lib/fa'
import { MdCheck } from 'react-icons/lib/md'
import QRCode from 'qrcode.react'
import Modal from './Modal'
import { btc } from '../../../../utils'
import styles from './Invoices.scss'
@ -24,7 +26,6 @@ class Invoices extends Component {
invoice ?
<div className={styles.invoiceModal}>
<h3>{invoice.memo}</h3>
<p className={styles.paymentRequest}>{invoice.payment_request}</p>
<h1>
{
ticker.currency === 'btc' ?
@ -41,6 +42,23 @@ class Invoices extends Component {
}
</span>
</h1>
<div className={styles.qrcode}>
<QRCode value={invoice.payment_request} size={200} />
<input
readOnly
className={styles.paymentRequest}
onClick={(event) => event.target.select()}
defaultValue={invoice.payment_request}
/>
</div>
<div className={styles.settled}>
{
invoice.settled ?
<p><MdCheck style={{ verticalAlign: 'top' }} /> Paid</p>
:
<p>Not Paid</p>
}
</div>
<p className={styles.date}>
Created on
<Moment format='MMM Do'>

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

@ -11,22 +11,46 @@
margin-bottom: 10px;
}
.paymentRequest {
text-align: center;
font-size: 8px;
}
h1 {
text-align: center;
color: $main;
margin: 60px 30px 60px 0;
margin: 20px 20px 60px 0;
svg {
font-size: 30px;
font-size: 20px;
}
.value {
font-size: 80px;
font-size: 60px;
}
}
.qrcode {
text-align: center;
.paymentRequest {
text-align: center;
font-size: 0.5vw;
margin-top: 20px;
padding: 5px;
border-radius: 5px;
background: $lightgrey;
border: 1px solid $darkgrey;
display: block;
width: 100%;
}
}
.settled {
text-align: center;
color: $main;
text-transform: uppercase;
font-size: 20px;
margin: 30px 0;
font-weight: bold;
svg {
line-height: 20px;
}
}

2
app/routes/app/components/components/Form/Form.js

@ -52,7 +52,7 @@ class Form extends Component {
<input
type='text'
size=''
style={{ width: `${(amount.length * 20) + 10}%`, fontSize: `${190 - (amount.length ** 2)}px` }}
style={{ width: `${amount.length > 1 ? (amount.length * 15) - 5 : 25}%`, fontSize: `${190 - (amount.length ** 2)}px` }}
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>

2
app/routes/app/components/components/Form/Form.scss

@ -53,7 +53,7 @@
margin: 0 auto;
display: flex;
flex-direction: column;
height: 100vh;
height: 75vh;
justify-content: center;
align-items: center;

85
app/routes/wallet/components/Wallet.js

@ -1,12 +1,93 @@
// @flow
import React, { Component } from 'react'
import ReactSVG from 'react-svg'
import { FaCircle } from 'react-icons/lib/fa'
import styles from './Wallet.scss'
class Wallet extends Component {
componentWillMount() {
const { fetchInfo, fetchPeers, fetchChannels } = this.props
fetchInfo()
fetchPeers()
fetchChannels()
}
render() {
const {
info,
peers: { peersLoading, peers },
channels: { channelsLoading, channels }
} = this.props
return (
<div>
Wallet
<div className={styles.wallet}>
<section className={styles.header}>
<ReactSVG path='../resources/zap_2.svg' />
<h1>{info.data.identity_pubkey}</h1>
</section>
<section className={styles.walletData}>
<div className={styles.peers}>
<h3>Connected Peers</h3>
<ul>
</ul>
</div>
<div className={styles.channels}>
<h3>Channels</h3>
<ul>
{
!channelsLoading && channels.length ?
channels.map(channel => {
console.log('channel: ', channel)
return (
<li key={channel.chan_id} className={styles.channel}>
<div className={styles.left}>
<section className={styles.remotePubkey}>
<span>
Remote Pubkey
</span>
<h4>
{channel.remote_pubkey}
</h4>
</section>
<section className={styles.channelPoint}>
<span>
Channel Point
</span>
<h4>
{channel.channel_point}
</h4>
</section>
</div>
<div className={styles.right}>
<section className={styles.capacity}>
<span>
Capacity
</span>
<h2>
{channel.capacity}
</h2>
</section>
<div className={styles.balances}>
<section>
<h4>{channel.local_balance}</h4>
<span>Local</span>
</section>
<section>
<h4>{channel.remote_balance}</h4>
<span>Remote</span>
</section>
</div>
</div>
</li>
)
})
:
'Loading...'
}
</ul>
</div>
</section>
</div>
)
}

112
app/routes/wallet/components/Wallet.scss

@ -0,0 +1,112 @@
@import '../../../variables.scss';
.wallet {
background: $lightgrey;
height: 100vh;
}
.header {
background: $white;
padding: 80px 30px;
text-align: center;
border-bottom: 1px solid $darkgrey;
svg {
width: 100px;
height: 100px;
}
h1 {
color: $black;
font-size: 20px;
margin: 20px 0;
}
}
.walletData {
padding: 60px 40px;
.peers, .channels {
width: 75%;
margin: 50px auto;
h3 {
text-transform: uppercase;
color: $darkestgrey;
letter-spacing: 1.6px;
font-size: 14px;
font-weight: 400;
margin-bottom: 10px;
}
}
}
.channel {
position: relative;
background: $white;
padding: 10px;
display: flex;
flex-direction: row;
justify-content: space-between;
.left, .right {
padding: 0 10px;
margin-bottom: 5;
section {
margin-bottom: 20px;
span {
text-transform: uppercase;
letter-spacing: 1.6px;
color: $black;
font-size: 10px;
font-weight: bold;
}
h2 {
font-size: 30px;
padding: 5px 0;
color: $main;
}
h4 {
margin-top: 5px;
}
}
}
.left {
flex: 7;
border-right: 1px solid $grey;
}
.right {
flex: 3;
.capacity {
text-align: center;
border-bottom: 1px solid $grey;
margin-bottom: 10px;
}
.balances {
display: flex;
justify-content: space-between;
section {
flex: 5;
text-align: center;
h4 {
color: $main;
font-size: 20px;
}
&:first-child {
border-right: 1px solid $grey;
}
}
}
}
}

15
app/routes/wallet/containers/WalletContainer.js

@ -1,8 +1,19 @@
import { connect } from 'react-redux'
import { fetchInfo } from '../../../reducers/info'
import { fetchPeers } from '../../../reducers/peers'
import { fetchChannels } from '../../../reducers/channels'
import Wallet from '../components/Wallet'
const mapDispatchToProps = {}
const mapDispatchToProps = {
fetchInfo,
fetchPeers,
fetchChannels
}
const mapStateToProps = (state) => ({})
const mapStateToProps = (state) => ({
info: state.info,
peers: state.peers,
channels: state.channels
})
export default connect(mapStateToProps, mapDispatchToProps)(Wallet)

5
app/variables.scss

@ -8,4 +8,7 @@ $traditionalgrey: #cccccc;
$lightgrey: #F7F7F7;
$darkgrey: #EBEBEB;
$darkestgrey: #999999;
$bluegrey: #555459;
$bluegrey: #555459;
$green: #0bb634;
$red: #ff0b00;

33
package-lock.json

@ -12143,6 +12143,20 @@
"integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
"dev": true
},
"qr.js": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
"integrity": "sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8="
},
"qrcode.react": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-0.7.1.tgz",
"integrity": "sha1-b8UBfxcCUEiRkRVYHaXjdbCUZ0I=",
"requires": {
"prop-types": "15.5.10",
"qr.js": "0.0.0"
}
},
"qs": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
@ -12373,6 +12387,11 @@
"prop-types": "15.5.10"
}
},
"react-render-to-json": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/react-render-to-json/-/react-render-to-json-0.0.4.tgz",
"integrity": "sha1-DbWI4pUs6gWmajOQVUxGw+p00AY="
},
"react-router": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.1.2.tgz",
@ -12416,6 +12435,15 @@
"svg-injector": "1.1.3"
}
},
"react-svg-morph": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/react-svg-morph/-/react-svg-morph-0.1.10.tgz",
"integrity": "sha1-eAz2gjpqtkChNn5Dt8lQnWgVe/M=",
"requires": {
"react-render-to-json": "0.0.4",
"svgpath": "2.2.1"
}
},
"react-test-renderer": {
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-15.6.1.tgz",
@ -14514,6 +14542,11 @@
"whet.extend": "0.9.9"
}
},
"svgpath": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.2.1.tgz",
"integrity": "sha1-CDS7Z8iadkcrK9BswQH6e1F7Iiw="
},
"symbol-observable": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz",

2
package.json

@ -188,6 +188,7 @@
"font-awesome": "^4.7.0",
"history": "^4.6.3",
"moment-timezone": "^0.5.13",
"qrcode.react": "^0.7.1",
"react": "^15.6.1",
"react-addons-css-transition-group": "^15.6.0",
"react-dom": "^15.6.1",
@ -201,6 +202,7 @@
"react-router-dom": "^4.1.1",
"react-router-redux": "^5.0.0-alpha.6",
"react-svg": "^2.1.21",
"react-svg-morph": "^0.1.10",
"redux": "^3.7.1",
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1",

Loading…
Cancel
Save