Jack Mallers
7 years ago
22 changed files with 757 additions and 67 deletions
@ -0,0 +1,54 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
import Isvg from 'react-inlinesvg' |
||||
|
|
||||
|
// import Transaction from './Transaction'
|
||||
|
// import Payment from './Payment'
|
||||
|
import InvoiceModal from './InvoiceModal' |
||||
|
|
||||
|
import x from 'icons/x.svg' |
||||
|
import styles from './ActivityModal.scss' |
||||
|
|
||||
|
const ActivityModal = ({ |
||||
|
modalType, |
||||
|
modalProps, |
||||
|
ticker, |
||||
|
currentTicker, |
||||
|
|
||||
|
hideActivityModal, |
||||
|
toggleCurrencyProps |
||||
|
}) => { |
||||
|
const MODAL_COMPONENTS = { |
||||
|
// TRANSACTION: Transaction,
|
||||
|
// PAYMENT: Payment,
|
||||
|
INVOICE: InvoiceModal |
||||
|
} |
||||
|
|
||||
|
if (!modalType) { return null } |
||||
|
|
||||
|
const SpecificModal = MODAL_COMPONENTS[modalType] |
||||
|
console.log('toggleCurrencyProps: ', toggleCurrencyProps) |
||||
|
return ( |
||||
|
<div className={styles.container}> |
||||
|
<div className={styles.closeContainer}> |
||||
|
<span onClick={() => hideActivityModal()}> |
||||
|
<Isvg src={x} /> |
||||
|
</span> |
||||
|
</div> |
||||
|
<SpecificModal |
||||
|
{...modalProps} |
||||
|
ticker={ticker} |
||||
|
currentTicker={currentTicker} |
||||
|
toggleCurrencyProps={toggleCurrencyProps} |
||||
|
/> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
ActivityModal.propTypes = { |
||||
|
modalType: PropTypes.string, |
||||
|
modalProps: PropTypes.object.isRequired, |
||||
|
hideActivityModal: PropTypes.func.isRequired |
||||
|
} |
||||
|
|
||||
|
export default ActivityModal |
@ -0,0 +1,27 @@ |
|||||
|
@import '../../variables.scss'; |
||||
|
|
||||
|
.container { |
||||
|
position: relative; |
||||
|
height: 100vh; |
||||
|
background: $bluegrey; |
||||
|
} |
||||
|
|
||||
|
.closeContainer { |
||||
|
text-align: right; |
||||
|
padding: 20px 40px 0px; |
||||
|
|
||||
|
span { |
||||
|
cursor: pointer; |
||||
|
opacity: 1.0; |
||||
|
transition: 0.25s all; |
||||
|
|
||||
|
&:hover { |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
svg { |
||||
|
color: $white; |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,106 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
|
||||
|
import Moment from 'react-moment' |
||||
|
import 'moment-timezone' |
||||
|
|
||||
|
import QRCode from 'qrcode.react' |
||||
|
import copy from 'copy-to-clipboard' |
||||
|
import { showNotification } from 'notifications' |
||||
|
|
||||
|
import { FaAngleDown } from 'react-icons/lib/fa' |
||||
|
|
||||
|
import { btc } from 'utils' |
||||
|
import Value from 'components/Value' |
||||
|
|
||||
|
import styles from './InvoiceModal.scss' |
||||
|
|
||||
|
|
||||
|
const InvoiceModal = ({ |
||||
|
invoice, |
||||
|
ticker, |
||||
|
currentTicker, |
||||
|
|
||||
|
toggleCurrencyProps: { |
||||
|
setActivityModalCurrencyFilters, |
||||
|
showCurrencyFilters, |
||||
|
currencyName, |
||||
|
currentCurrencyFilters, |
||||
|
setCurrency |
||||
|
} |
||||
|
}) => { |
||||
|
const copyPaymentRequest = () => { |
||||
|
copy(invoice.payment_request) |
||||
|
showNotification('Noice', 'Successfully copied to clipboard') |
||||
|
} |
||||
|
|
||||
|
const onCurrencyFilterClick = (currency) => { |
||||
|
setCurrency(currency) |
||||
|
setActivityModalCurrencyFilters(false) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<div className={styles.container}> |
||||
|
<div className={styles.content}> |
||||
|
<section className={styles.left}> |
||||
|
<QRCode |
||||
|
value={invoice.payment_request} |
||||
|
renderAs='svg' |
||||
|
size={150} |
||||
|
bgColor='transparent' |
||||
|
fgColor='white' |
||||
|
level='L' |
||||
|
/> |
||||
|
</section> |
||||
|
<section className={styles.right}> |
||||
|
<div className={styles.details}> |
||||
|
<section className={styles.amount}> |
||||
|
<h1> |
||||
|
<Value value={invoice.value} currency={ticker.currency} currentTicker={currentTicker} /> |
||||
|
</h1> |
||||
|
<section className={styles.currentCurrency} onClick={() => setActivityModalCurrencyFilters(!showCurrencyFilters)}> |
||||
|
<span>{currencyName}</span><span><FaAngleDown /></span> |
||||
|
</section> |
||||
|
<ul className={showCurrencyFilters && styles.active}> |
||||
|
{ |
||||
|
currentCurrencyFilters.map(filter => |
||||
|
<li key={filter.key} onClick={() => onCurrencyFilterClick(filter.key)}>{filter.name}</li> |
||||
|
) |
||||
|
} |
||||
|
</ul> |
||||
|
</section> |
||||
|
<section className={styles.date}> |
||||
|
<p> |
||||
|
<Moment format='MM/DD/YYYY'>{invoice.creation_date * 1000}</Moment> |
||||
|
</p> |
||||
|
<p className={styles.notPaid}> |
||||
|
{!invoice.settled && 'Not Paid'} |
||||
|
</p> |
||||
|
</section> |
||||
|
</div> |
||||
|
|
||||
|
<div className={styles.memo}> |
||||
|
<h4>Memo</h4> |
||||
|
<p>{invoice.memo}</p> |
||||
|
</div> |
||||
|
|
||||
|
<div className={styles.request}> |
||||
|
<h4>Request</h4> |
||||
|
<p>{invoice.payment_request}</p> |
||||
|
</div> |
||||
|
</section> |
||||
|
</div> |
||||
|
|
||||
|
<div className={styles.actions}> |
||||
|
<div>Save as image</div> |
||||
|
<div>Copy Request</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
InvoiceModal.propTypes = { |
||||
|
invoice: PropTypes.object.isRequired |
||||
|
} |
||||
|
|
||||
|
export default InvoiceModal |
@ -0,0 +1,143 @@ |
|||||
|
@import '../../variables.scss'; |
||||
|
|
||||
|
.container { |
||||
|
color: $white; |
||||
|
} |
||||
|
|
||||
|
.content { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
background: $spaceblue; |
||||
|
width: 85%; |
||||
|
margin: 50px auto; |
||||
|
padding: 30px 0; |
||||
|
|
||||
|
.left { |
||||
|
width: 25%; |
||||
|
padding: 0 60px; |
||||
|
} |
||||
|
|
||||
|
.right { |
||||
|
width: 75%; |
||||
|
min-height: 220px; |
||||
|
border-left: 1px solid $spaceborder; |
||||
|
padding: 10px 60px; |
||||
|
|
||||
|
.details { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
margin-bottom: 40px; |
||||
|
|
||||
|
.amount { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
position: relative; |
||||
|
|
||||
|
h1 { |
||||
|
font-size: 40px; |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
|
||||
|
.currentCurrency { |
||||
|
cursor: pointer; |
||||
|
transition: 0.25s all; |
||||
|
|
||||
|
&:hover { |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
|
||||
|
span { |
||||
|
font-size: 14px; |
||||
|
|
||||
|
&:nth-child(1) { |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
ul { |
||||
|
visibility: hidden; |
||||
|
position: absolute; |
||||
|
top: 40px; |
||||
|
right: -50px; |
||||
|
|
||||
|
&.active { |
||||
|
visibility: visible; |
||||
|
} |
||||
|
|
||||
|
li { |
||||
|
padding: 8px 15px; |
||||
|
background: #191919; |
||||
|
cursor: pointer; |
||||
|
transition: 0.25s hover; |
||||
|
border-bottom: 1px solid #0f0f0f; |
||||
|
|
||||
|
&:hover { |
||||
|
background: #0f0f0f; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.date { |
||||
|
font-size: 12px; |
||||
|
text-align: right; |
||||
|
|
||||
|
.notPaid { |
||||
|
color: #FF8A65; |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.memo, .request { |
||||
|
h4 { |
||||
|
font-size: 10px; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
word-wrap: break-word; |
||||
|
max-width: 450px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.memo { |
||||
|
margin-bottom: 40px; |
||||
|
|
||||
|
p { |
||||
|
font-size: 20px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.request p { |
||||
|
font-size: 10px; |
||||
|
max-width: 450px; |
||||
|
line-height: 1.5; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.actions { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: center; |
||||
|
|
||||
|
div { |
||||
|
text-align: center; |
||||
|
margin: 35px 10px; |
||||
|
width: 235px; |
||||
|
padding: 20px 10px; |
||||
|
background: #31343f; |
||||
|
cursor: pointer; |
||||
|
transition: 0.25s all; |
||||
|
|
||||
|
&:hover { |
||||
|
background: darken(#31343f, 5%); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,111 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
|
||||
|
import Isvg from 'react-inlinesvg' |
||||
|
import hand from 'icons/hand.svg' |
||||
|
import { FaAngleDown } from 'react-icons/lib/fa' |
||||
|
|
||||
|
import { btc } from 'utils' |
||||
|
import CurrencyIcon from 'components/CurrencyIcon' |
||||
|
import styles from './Request.scss' |
||||
|
|
||||
|
const Request = ({ |
||||
|
requestform: { amount, memo, showCurrencyFilters }, |
||||
|
ticker, |
||||
|
|
||||
|
setRequestAmount, |
||||
|
setRequestMemo, |
||||
|
setCurrency, |
||||
|
setRequestCurrencyFilters, |
||||
|
currencyName, |
||||
|
|
||||
|
currentCurrencyFilters, |
||||
|
|
||||
|
onRequestSubmit |
||||
|
}) => { |
||||
|
const onCurrencyFilterClick = (currency) => { |
||||
|
// change the input amount
|
||||
|
setRequestAmount(btc.convert(ticker.currency, currency, amount)) |
||||
|
|
||||
|
setCurrency(currency) |
||||
|
setRequestCurrencyFilters(false) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<div className={styles.container}> |
||||
|
<header className={styles.header}> |
||||
|
<Isvg src={hand} /> |
||||
|
<h1>Request Payment</h1> |
||||
|
</header> |
||||
|
|
||||
|
<div className={styles.content}> |
||||
|
<section className={styles.memo}> |
||||
|
<div className={styles.top}> |
||||
|
<label htmlFor='memo'>Memo</label> |
||||
|
</div> |
||||
|
<div className={styles.bottom}> |
||||
|
<input |
||||
|
type='text' |
||||
|
placeholder='Dinner, Rent, etc' |
||||
|
value={memo} |
||||
|
onChange={event => setRequestMemo(event.target.value)} |
||||
|
id='memo' |
||||
|
/> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section className={styles.amount}> |
||||
|
<div className={styles.top}> |
||||
|
<label htmlFor='amount'>Amount</label> |
||||
|
<span></span> |
||||
|
</div> |
||||
|
<div className={styles.bottom}> |
||||
|
<input |
||||
|
type='number' |
||||
|
value={amount || ''} |
||||
|
onChange={event => setRequestAmount(event.target.value)} |
||||
|
id='amount' |
||||
|
placeholder='0.00000000' |
||||
|
/> |
||||
|
<div className={styles.currency}> |
||||
|
<section className={styles.currentCurrency} onClick={() => setRequestCurrencyFilters(!showCurrencyFilters)}> |
||||
|
<span>{currencyName}</span><span><FaAngleDown /></span> |
||||
|
</section> |
||||
|
<ul className={showCurrencyFilters && styles.active}> |
||||
|
{ |
||||
|
currentCurrencyFilters.map(filter => |
||||
|
<li key={filter.key} onClick={() => onCurrencyFilterClick(filter.key)}>{filter.name}</li> |
||||
|
) |
||||
|
} |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div className={styles.usdAmount}> |
||||
|
|
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section className={styles.submit}> |
||||
|
<div className={`${styles.button} ${amount > 0 && styles.active}`} onClick={onRequestSubmit}> |
||||
|
Request |
||||
|
</div> |
||||
|
</section> |
||||
|
</div> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
Request.propTypes = { |
||||
|
requestform: PropTypes.shape({ |
||||
|
amount: PropTypes.string, |
||||
|
memo: PropTypes.string |
||||
|
}).isRequired, |
||||
|
|
||||
|
setRequestAmount: PropTypes.func.isRequired, |
||||
|
setRequestMemo: PropTypes.func.isRequired, |
||||
|
|
||||
|
onRequestSubmit: PropTypes.func.isRequired |
||||
|
} |
||||
|
|
||||
|
export default Request |
@ -0,0 +1,147 @@ |
|||||
|
@import '../../variables.scss'; |
||||
|
|
||||
|
.container { |
||||
|
padding: 0 40px; |
||||
|
font-family: Roboto; |
||||
|
} |
||||
|
|
||||
|
.header { |
||||
|
text-align: center; |
||||
|
padding-bottom: 20px; |
||||
|
color: $white; |
||||
|
border-bottom: 1px solid $spaceborder; |
||||
|
|
||||
|
h1 { |
||||
|
font-size: 22px; |
||||
|
font-weight: 100; |
||||
|
margin-top: 10px; |
||||
|
letter-spacing: 1.5px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.content { |
||||
|
margin-top: 50px; |
||||
|
color: $white; |
||||
|
|
||||
|
.memo { |
||||
|
margin-bottom: 25px; |
||||
|
} |
||||
|
|
||||
|
.amount .bottom { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
|
||||
|
input { |
||||
|
font-size: 40px; |
||||
|
max-width: 230px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.top { |
||||
|
margin-bottom: 25px; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
|
||||
|
label { |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.bottom { |
||||
|
input { |
||||
|
background: transparent; |
||||
|
outline: none; |
||||
|
border: 0; |
||||
|
color: $gold; |
||||
|
-webkit-text-fill-color: $white; |
||||
|
font-size: 20px; |
||||
|
width: 100%; |
||||
|
font-weight: 200; |
||||
|
} |
||||
|
|
||||
|
input::-webkit-input-placeholder { |
||||
|
text-shadow: none; |
||||
|
-webkit-text-fill-color: initial; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.currency { |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
|
||||
|
.currentCurrency { |
||||
|
cursor: pointer; |
||||
|
transition: 0.25s all; |
||||
|
|
||||
|
&:hover { |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
|
||||
|
span { |
||||
|
font-size: 14px; |
||||
|
|
||||
|
&:nth-child(1) { |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
ul { |
||||
|
visibility: hidden; |
||||
|
position: absolute; |
||||
|
top: 30px; |
||||
|
|
||||
|
&.active { |
||||
|
visibility: visible; |
||||
|
} |
||||
|
|
||||
|
li { |
||||
|
padding: 8px 15px; |
||||
|
background: #191919; |
||||
|
cursor: pointer; |
||||
|
transition: 0.25s hover; |
||||
|
border-bottom: 1px solid #0f0f0f; |
||||
|
|
||||
|
&:hover { |
||||
|
background: #0f0f0f; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.usdAmount { |
||||
|
margin-top: 20px; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
|
||||
|
.submit { |
||||
|
margin-top: 50px; |
||||
|
text-align: center; |
||||
|
|
||||
|
.button { |
||||
|
width: 235px; |
||||
|
margin: 0 auto; |
||||
|
padding: 20px 10px; |
||||
|
background: #31343f; |
||||
|
opacity: 0.5; |
||||
|
cursor: pointer; |
||||
|
transition: 0.25s all; |
||||
|
|
||||
|
&.active { |
||||
|
background: $gold; |
||||
|
opacity: 1.0; |
||||
|
|
||||
|
&:hover { |
||||
|
background: darken($gold, 5%); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 897 B After Width: | Height: | Size: 803 B |
@ -1,13 +1,27 @@ |
|||||
@import '../../../../../variables.scss'; |
@import '../../../../../variables.scss'; |
||||
|
|
||||
|
.container { |
||||
|
position: relative; |
||||
|
height: 100vh; |
||||
|
background: $spaceblue; |
||||
|
} |
||||
|
|
||||
.closeContainer { |
.closeContainer { |
||||
background: $lightgrey; |
|
||||
text-align: right; |
text-align: right; |
||||
padding: 10px; |
padding: 20px 40px 0px; |
||||
|
|
||||
span { |
span { |
||||
color: $darkestgrey; |
|
||||
font-size: 20px; |
|
||||
cursor: pointer; |
cursor: pointer; |
||||
|
opacity: 1.0; |
||||
|
transition: 0.25s all; |
||||
|
|
||||
|
&:hover { |
||||
|
opacity: 0.5; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
|
svg { |
||||
|
color: $white; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Loading…
Reference in new issue