Browse Source

feature(channelform): step one of the new channel form

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
e42e9c4ba5
  1. 39
      app/app.global.scss
  2. 61
      app/components/ChannelForm/ChannelForm.js
  3. 36
      app/components/ChannelForm/ChannelForm.scss
  4. 27
      app/components/ChannelForm/Footer.js
  5. 8
      app/components/ChannelForm/Footer.scss
  6. 48
      app/components/ChannelForm/StepOne.js
  7. 76
      app/components/ChannelForm/StepOne.scss
  8. 3
      app/components/ChannelForm/index.js
  9. 106
      app/reducers/channelform.js
  10. 2
      app/reducers/index.js
  11. 26
      app/routes/channels/components/Channels.js
  12. 49
      app/routes/channels/containers/ChannelsContainer.js

39
app/app.global.scss

@ -100,3 +100,42 @@ body {
outline: 0;
}
}
.buttonContainer.circleContainer {
display: inline-block;
width: auto;
min-width: 0;
background: none;
border: none;
box-shadow: none;
}
.buttonContainer .circle {
display: inline-block;
border-radius: 50px;
}
.buttonContainer .circle.small {
width: 50px;
padding: 10px 0;
}
.buttonContainer.small {
min-width: auto;
padding: 0;
border: none;
margin: 0 auto;
width: 80%;
}
.buttonContainer .small.active {
box-shadow: inset 0 1px 1px 1px #1f4b2e;
transform: translate(0px, 3px);
outline: 0;
background: #002280;
}
.buttonContainer.small .buttonPrimary {
padding: 10px 5px;
font-size: 15px;
}

61
app/components/ChannelForm/ChannelForm.js

@ -0,0 +1,61 @@
import React from 'react'
import PropTypes from 'prop-types'
import ReactModal from 'react-modal'
import StepOne from './StepOne'
import Footer from './Footer'
import styles from './ChannelForm.scss'
const ChannelForm = ({
channelform,
closeChannelForm,
changeStep,
setNodeKey,
channelFormHeader,
channelFormProgress,
peers
}) => {
const renderStep = () => {
const { step } = channelform
console.log('setNodeKey: ', setNodeKey)
switch (step) {
case 1:
return <StepOne peers={peers} changeStep={changeStep} setNodeKey={setNodeKey} />
case 2:
return 'Step Two'
case 3:
return 'Step 3'
default:
return 'Confirm Step'
}
}
return (
<ReactModal
isOpen={channelform.isOpen}
ariaHideApp
shouldCloseOnOverlayClick
contentLabel='No Overlay Click Modal'
onRequestClose={closeChannelForm}
parentSelector={() => document.body}
className={styles.modal}
>
<header className={styles.header}>
<h3>{channelFormHeader}</h3>
<div className={styles.progress} style={{ width: `${channelFormProgress}%` }}></div>
</header>
<div className={styles.content}>
{renderStep()}
</div>
<Footer step={channelform.step} />
</ReactModal>
)
}
ChannelForm.propTypes = {}
export default ChannelForm

36
app/components/ChannelForm/ChannelForm.scss

@ -0,0 +1,36 @@
@import '../../variables.scss';
.modal {
width: 40%;
min-height: 500px;
margin: 50px auto;
position: absolute;
top: auto;
left: 20%;
right: 0;
bottom: auto;
background: $white;
outline: none;
z-index: -2;
border: 1px solid $darkgrey;
}
.header {
padding: 20px;
background: $lightgrey;
text-align: center;
font-family: 'Jigsaw Light';
text-transform: uppercase;
position: relative;
z-index: -2;
}
.progress {
transition: all 0.2s ease;
background: $main;
position: absolute;
height: 100%;
top: 0;
left: 0;
z-index: -1;
}

27
app/components/ChannelForm/Footer.js

@ -0,0 +1,27 @@
import React from 'react'
import PropTypes from 'prop-types'
import { FaArrowLeft, FaArrowRight } from 'react-icons/lib/fa'
import styles from './Footer.scss'
const Footer = ({ step }) => {
if ( step === 1 ) { return null }
return (
<div className={styles.footer}>
<div className='buttonContainer circleContainer'>
<div className='buttonPrimary circle'>
<FaArrowLeft />
</div>
</div>
<div className='buttonContainer circleContainer'>
<div className='buttonPrimary circle'>
<FaArrowRight />
</div>
</div>
</div>
)
}
Footer.propTypes = {}
export default Footer

8
app/components/ChannelForm/Footer.scss

@ -0,0 +1,8 @@
.footer {
text-align: center;
padding-bottom: 30px;
div {
margin: 0 5px;
}
}

48
app/components/ChannelForm/StepOne.js

@ -0,0 +1,48 @@
import React from 'react'
import PropTypes from 'prop-types'
import { MdSearch } from 'react-icons/lib/md'
import styles from './StepOne.scss'
const StepOne = ({ peers, changeStep, setNodeKey }) => {
const peerClicked = (peer) => {
setNodeKey(peer.pub_key)
changeStep(2)
}
return (
<div>
<div className={styles.search}>
<label className={`${styles.label} ${styles.input}`} htmlFor='peersSearch'>
<MdSearch />
</label>
<input
value={''}
onChange={event => console.log('event: ', event)}
className={`${styles.text} ${styles.input}`}
placeholder='Search your peers by their public key'
type='text'
id='peersSearch'
/>
</div>
<ul className={styles.peers}>
{peers.length &&
peers.map(peer => (
<li
key={peer.peer_id}
className={styles.peer}
onClick={() => peerClicked(peer)}
>
<h4>{peer.address}</h4>
<h1>{peer.pub_key}</h1>
</li>
)
)}
</ul>
</div>
)
}
StepOne.propTypes = {}
export default StepOne

76
app/components/ChannelForm/StepOne.scss

@ -0,0 +1,76 @@
@import '../../variables.scss';
.peers {
// margin-bottom: 50px;
h2 {
text-transform: uppercase;
font-weight: 200;
padding: 10px 0;
border-bottom: 1px solid $grey;
color: $darkestgrey;
}
}
.search {
height: 50px;
padding: 2px;
border-bottom: 1px solid $darkgrey;
.input {
display: inline-block;
vertical-align: top;
height: 100%;
}
.label {
width: 5%;
line-height: 50px;
font-size: 16px;
text-align: center;
cursor: pointer;
}
.text {
width: 95%;
outline: 0;
padding: 0;
border: 0;
border-radius: 0;
height: 50px;
font-size: 16px;
}
}
.peer {
position: relative;
background: $white;
padding: 10px;
border-top: 1px solid $grey;
cursor: pointer;
transition: all 0.25s;
&:hover {
opacity: 0.5;
}
&:first-child {
border: none;
}
h4, h1 {
margin: 10px 0;
}
h4 {
font-size: 12px;
font-weight: bold;
color: $black;
}
h1 {
font-size: 14px;
font-weight: 200;
color: $main;
}
}

3
app/components/ChannelForm/index.js

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

106
app/reducers/channelform.js

@ -0,0 +1,106 @@
import { createSelector } from 'reselect'
// Initial State
const initialState = {
isOpen: false,
node_key: '',
local_amt: '',
push_amt: '',
step: 1
}
// Constants
// ------------------------------------
export const OPEN_CHANNEL_FORM = 'OPEN_CHANNEL_FORM'
export const CLOSE_CHANNEL_FORM = 'CLOSE_CHANNEL_FORM'
export const SET_NODE_KEY = 'SET_NODE_KEY'
export const CHANGE_STEP = 'CHANGE_STEP'
export const RESET_CHANNEL_FORM = 'RESET_CHANNEL_FORM'
// ------------------------------------
// Actions
// ------------------------------------
export function openChannelForm() {
return {
type: OPEN_CHANNEL_FORM
}
}
export function closeChannelForm() {
return {
type: CLOSE_CHANNEL_FORM
}
}
export function setNodeKey(node_key) {
return {
type: SET_NODE_KEY,
node_key
}
}
export function changeStep(step) {
return {
type: CHANGE_STEP,
step
}
}
export function resetChannelForm() {
return {
type: RESET_CHANNEL_FORM
}
}
// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[OPEN_CHANNEL_FORM]: state => ({ ...state, isOpen: true }),
[CLOSE_CHANNEL_FORM]: state => ({ ...state, isOpen: false }),
[SET_NODE_KEY]: (state, { node_key }) => ({ ...state, node_key }),
[CHANGE_STEP]: (state, { step }) => ({ ...state, step }),
[RESET_CHANNEL_FORM]: () => (initialState)
}
const channelFormSelectors = {}
const channelFormStepSelector = state => state.channelform.step
channelFormSelectors.channelFormHeader = createSelector(
channelFormStepSelector,
step => {
switch (step) {
case 1:
return 'Choose a peer'
case 2:
return 'Choose your local amount'
case 3:
return 'Choose your push amount'
default:
return 'Confirm'
}
}
)
channelFormSelectors.channelFormProgress = createSelector(
channelFormStepSelector,
step => (step / 4) * 100
)
export { channelFormSelectors }
// ------------------------------------
// Reducer
// ------------------------------------
export default function channelFormReducer(state = initialState, action) {
const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state
}

2
app/reducers/index.js

@ -8,6 +8,7 @@ import balance from './balance'
import payment from './payment'
import peers from './peers'
import channels from './channels'
import channelform from './channelform'
import form from './form'
import payform from './payform'
@ -29,6 +30,7 @@ const rootReducer = combineReducers({
payment,
peers,
channels,
channelform,
form,
payform,

26
app/routes/channels/components/Channels.js

@ -5,12 +5,16 @@ import { FaAlignJustify, FaThLarge } from 'react-icons/lib/fa'
import { MdSearch } from 'react-icons/lib/md'
import Channel from 'components/Channels/Channel'
import ChannelForm from 'components/ChannelForm'
import styles from './Channels.scss'
class Channels extends Component {
componentWillMount() {
this.props.fetchChannels()
const { fetchChannels, fetchPeers } = this.props
fetchChannels()
fetchPeers()
}
render() {
@ -18,13 +22,25 @@ class Channels extends Component {
channels: { channels },
allChannels,
closeChannelForm,
openChannelForm,
channelform,
channelFormHeader,
channelFormProgress,
peers: { peers },
ticker,
currentTicker
currentTicker,
channelFormProps
} = this.props
console.log('channels: ', channels)
console.log('channelFormProps: ', channelFormProps)
return (
<div className={styles.container}>
<ChannelForm {...channelFormProps} />
<div className={styles.search}>
<label className={`${styles.label} ${styles.input}`} htmlFor='channelSearch'>
<MdSearch />
@ -48,7 +64,7 @@ class Channels extends Component {
</span>
</div>
<div className={styles.createChannelContainer}>
<div className='buttonPrimary'>
<div className='buttonPrimary' onClick={openChannelForm}>
Create new channel
</div>
</div>
@ -58,8 +74,6 @@ class Channels extends Component {
<ul>
{
allChannels.map((channel, index) => {
console.log('channel: ', channel)
return (
<Channel
key={index}

49
app/routes/channels/containers/ChannelsContainer.js

@ -7,20 +7,63 @@ import {
channelsSelectors
} from 'reducers/channels'
import {
openChannelForm,
changeStep,
setNodeKey,
closeChannelForm,
channelFormSelectors
} from 'reducers/channelform'
import { fetchPeers } from 'reducers/peers'
import { tickerSelectors } from 'reducers/ticker'
import Channels from '../components/Channels'
const mapDispatchToProps = {
fetchChannels
fetchChannels,
openChannelForm,
closeChannelForm,
setNodeKey,
changeStep,
fetchPeers
}
const mapStateToProps = state => ({
channels: state.channels,
channelform: state.channelform,
peers: state.peers,
ticker: state.ticker,
allChannels: channelsSelectors.allChannels(state),
currentTicker: tickerSelectors.currentTicker(state)
currentTicker: tickerSelectors.currentTicker(state),
channelFormHeader: channelFormSelectors.channelFormHeader(state),
channelFormProgress: channelFormSelectors.channelFormProgress(state)
})
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Channels))
const mergeProps = (stateProps, dispatchProps, ownProps) => {
const channelFormProps = {
closeChannelForm: dispatchProps.closeChannelForm,
changeStep: dispatchProps.changeStep,
setNodeKey: dispatchProps.setNodeKey,
channelform: stateProps.channelform,
channelFormHeader: stateProps.channelFormHeader,
channelFormProgress: stateProps.channelFormProgress,
peers: stateProps.peers.peers
}
return {
...stateProps,
...dispatchProps,
...ownProps,
channelFormProps
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps, mergeProps)(Channels))

Loading…
Cancel
Save