jackmallers
7 years ago
committed by
GitHub
39 changed files with 1199 additions and 210 deletions
@ -0,0 +1,50 @@ |
|||
$curve: cubic-bezier(0.650, 0.000, 0.450, 1.000); |
|||
|
|||
.checkmark__circle { |
|||
stroke-dasharray: 166; |
|||
stroke-dashoffset: 166; |
|||
stroke-width: 2; |
|||
stroke-miterlimit: 10; |
|||
stroke: $main; |
|||
fill: none; |
|||
animation: stroke .6s $curve forwards; |
|||
} |
|||
|
|||
.checkmark { |
|||
width: 56px; |
|||
height: 56px; |
|||
border-radius: 50%; |
|||
stroke-width: 2; |
|||
stroke: #fff; |
|||
stroke-miterlimit: 10; |
|||
box-shadow: inset 0px 0px 0px $main; |
|||
animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both; |
|||
} |
|||
|
|||
.checkmark__check { |
|||
transform-origin: 50% 50%; |
|||
stroke-dasharray: 48; |
|||
stroke-dashoffset: 48; |
|||
animation: stroke .3s $curve .8s forwards; |
|||
} |
|||
|
|||
@keyframes stroke { |
|||
100% { |
|||
stroke-dashoffset: 0; |
|||
} |
|||
} |
|||
|
|||
@keyframes scale { |
|||
0%, 100% { |
|||
transform: none; |
|||
} |
|||
50% { |
|||
transform: scale3d(1.1, 1.1, 1); |
|||
} |
|||
} |
|||
|
|||
@keyframes fill { |
|||
100% { |
|||
box-shadow: inset 0px 0px 0px 30px $main; |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
import React from 'react' |
|||
import Isvg from 'react-inlinesvg' |
|||
|
|||
const AnimatedCheckmark = () => <Isvg src={'./components/AnimatedCheckmark/checkmark.svg'} /> |
|||
|
|||
export default AnimatedCheckmark |
After Width: | Height: | Size: 238 B |
@ -0,0 +1,3 @@ |
|||
import AnimatedCheckmark from './AnimatedCheckmark' |
|||
|
|||
export default AnimatedCheckmark |
@ -0,0 +1,15 @@ |
|||
import React from 'react' |
|||
import path from 'path' |
|||
import Isvg from 'react-inlinesvg' |
|||
import styles from './LoadingBolt.scss' |
|||
|
|||
const LoadingBolt = () => ( |
|||
<div className={styles.container}> |
|||
<div className={styles.content}> |
|||
<Isvg className={styles.bolt} src={path.join(__dirname, '..', 'resources/cloudbolt.svg')} /> |
|||
<h1>loading</h1> |
|||
</div> |
|||
</div> |
|||
) |
|||
|
|||
export default LoadingBolt |
@ -0,0 +1,29 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
z-index: 1000; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: $white; |
|||
text-align: center; |
|||
} |
|||
|
|||
.content { |
|||
position: relative; |
|||
top: calc(50% - 250px); |
|||
min-height: 250px; |
|||
|
|||
.bolt svg { |
|||
height: 150px; |
|||
width: 150px; |
|||
} |
|||
|
|||
h1 { |
|||
color: $main; |
|||
margin-top: 50px; |
|||
font-size: 25px; |
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
import LoadingBolt from './LoadingBolt' |
|||
|
|||
export default LoadingBolt |
@ -0,0 +1,47 @@ |
|||
// ------------------------------------
|
|||
// Initial State
|
|||
// ------------------------------------
|
|||
const initialState = { |
|||
modalType: null, |
|||
modalProps: {} |
|||
} |
|||
|
|||
// ------------------------------------
|
|||
// Constants
|
|||
// ------------------------------------
|
|||
export const SHOW_MODAL = 'SHOW_MODAL' |
|||
export const HIDE_MODAL = 'HIDE_MODAL' |
|||
|
|||
// ------------------------------------
|
|||
// Actions
|
|||
// ------------------------------------
|
|||
export function showModal(modalType, modalProps) { |
|||
return { |
|||
type: SHOW_MODAL, |
|||
modalType, |
|||
modalProps |
|||
} |
|||
} |
|||
|
|||
export function hideModal() { |
|||
return { |
|||
type: HIDE_MODAL |
|||
} |
|||
} |
|||
|
|||
// ------------------------------------
|
|||
// Action Handlers
|
|||
// ------------------------------------
|
|||
const ACTION_HANDLERS = { |
|||
[SHOW_MODAL]: (state, { modalType, modalProps }) => ({ ...state, modalType, modalProps }), |
|||
[HIDE_MODAL]: () => initialState |
|||
} |
|||
|
|||
// ------------------------------------
|
|||
// Reducer
|
|||
// ------------------------------------
|
|||
export default function modalReducer(state = initialState, action) { |
|||
const handler = ACTION_HANDLERS[action.type] |
|||
|
|||
return handler ? handler(state, action) : state |
|||
} |
@ -0,0 +1,146 @@ |
|||
import React, { Component } from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { FaBolt, FaChain } from 'react-icons/lib/fa' |
|||
import CurrencyIcon from '../../../../../../../components/CurrencyIcon' |
|||
import LoadingBolt from '../../../../../../../components/LoadingBolt' |
|||
import { btc } from '../../../../../../../utils' |
|||
import styles from './Pay.scss' |
|||
|
|||
class Pay extends Component { |
|||
componentDidUpdate(prevProps) { |
|||
const { isOnchain, isLn, fetchInvoice, payment_request } = this.props |
|||
|
|||
if (isOnchain) { this.amountInput.focus() } |
|||
if ((prevProps.payment_request !== payment_request) && isLn) { fetchInvoice(payment_request) } |
|||
} |
|||
|
|||
render() { |
|||
const { |
|||
sendingPayment, |
|||
invoiceAmount, |
|||
onchainAmount, |
|||
setOnchainAmount, |
|||
payment_request, |
|||
setPaymentRequest, |
|||
payInvoice, |
|||
sendCoins, |
|||
currentTicker, |
|||
currency, |
|||
crypto, |
|||
isOnchain, |
|||
isLn |
|||
} = this.props |
|||
|
|||
const payClicked = () => { |
|||
if (!isOnchain && !isLn) { return } |
|||
|
|||
if (isOnchain) { sendCoins({ value: onchainAmount, addr: payment_request, currency, rate: currentTicker.price_usd }) } |
|||
if (isLn) { payInvoice(payment_request) } |
|||
} |
|||
|
|||
const calculateAmount = value => (currency === 'usd' ? btc.satoshisToUsd(value, currentTicker.price_usd) : btc.satoshisToBtc(value)) |
|||
|
|||
return ( |
|||
<div> |
|||
{ |
|||
sendingPayment ? |
|||
<LoadingBolt /> |
|||
: |
|||
null |
|||
|
|||
} |
|||
<div className={styles.container}> |
|||
<section className={`${styles.amountContainer} ${isLn ? styles.ln : ''}`}> |
|||
<label htmlFor='amount'> |
|||
<CurrencyIcon currency={currency} crypto={crypto} /> |
|||
</label> |
|||
<input |
|||
type='text' |
|||
ref={input => this.amountInput = input} // eslint-disable-line
|
|||
size='' |
|||
style={ |
|||
isLn ? |
|||
{ width: '75%', fontSize: '85px' } |
|||
: |
|||
{ width: `${onchainAmount.length > 1 ? (onchainAmount.length * 15) - 5 : 25}%`, fontSize: `${190 - (onchainAmount.length ** 2)}px` } |
|||
} |
|||
value={isLn ? calculateAmount(invoiceAmount) : onchainAmount} |
|||
onChange={event => setOnchainAmount(event.target.value)} |
|||
id='amount' |
|||
readOnly={isLn} |
|||
/> |
|||
</section> |
|||
<div className={styles.inputContainer}> |
|||
<div className={styles.info}> |
|||
{(() => { |
|||
if (isOnchain) { |
|||
return ( |
|||
<span>{`You're about to send ${onchainAmount} ${currency.toUpperCase()} on-chain which should take around 10 minutes`}</span> |
|||
) |
|||
} else if (isLn) { |
|||
return ( |
|||
<span>{`You're about to send ${calculateAmount(invoiceAmount)} ${currency.toUpperCase()} over the Lightning Network which will be instant`}</span> // eslint-disable-line |
|||
) |
|||
} |
|||
return null |
|||
})()} |
|||
</div> |
|||
<aside className={styles.paymentIcon}> |
|||
{(() => { |
|||
if (isOnchain) { |
|||
return ( |
|||
<i> |
|||
<span>on-chain</span> |
|||
<FaChain /> |
|||
</i> |
|||
) |
|||
} else if (isLn) { |
|||
return ( |
|||
<i> |
|||
<span>lightning network</span> |
|||
<FaBolt /> |
|||
</i> |
|||
) |
|||
} |
|||
return null |
|||
})()} |
|||
</aside> |
|||
<section className={styles.input}> |
|||
<input |
|||
type='text' |
|||
placeholder='Payment request or bitcoin address' |
|||
value={payment_request} |
|||
onChange={event => setPaymentRequest(event.target.value)} |
|||
id='paymentRequest' |
|||
/> |
|||
</section> |
|||
</div> |
|||
<section className={styles.buttonGroup}> |
|||
<div className={styles.button} onClick={payClicked}> |
|||
Pay |
|||
</div> |
|||
</section> |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
|
|||
Pay.propTypes = { |
|||
sendingPayment: PropTypes.bool.isRequired, |
|||
invoiceAmount: PropTypes.string.isRequired, |
|||
onchainAmount: PropTypes.string.isRequired, |
|||
setOnchainAmount: PropTypes.func.isRequired, |
|||
payment_request: PropTypes.string.isRequired, |
|||
setPaymentRequest: PropTypes.func.isRequired, |
|||
fetchInvoice: PropTypes.func.isRequired, |
|||
payInvoice: PropTypes.func.isRequired, |
|||
sendCoins: PropTypes.func.isRequired, |
|||
currentTicker: PropTypes.object.isRequired, |
|||
currency: PropTypes.string.isRequired, |
|||
crypto: PropTypes.string.isRequired, |
|||
isOnchain: PropTypes.bool.isRequired, |
|||
isLn: PropTypes.bool.isRequired |
|||
} |
|||
|
|||
export default Pay |
@ -0,0 +1,142 @@ |
|||
@import '../../../../../../../variables.scss'; |
|||
|
|||
.container { |
|||
margin: 0 auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 75vh; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.amountContainer { |
|||
color: $main; |
|||
display: flex; |
|||
justify-content: center; |
|||
min-height: 120px; |
|||
margin-bottom: 20px; |
|||
min-height: 175px; |
|||
|
|||
&.ln { |
|||
opacity: 0.75; |
|||
} |
|||
|
|||
label, input[type=text] { |
|||
color: inherit; |
|||
display: inline-block; |
|||
vertical-align: top; |
|||
padding: 0; |
|||
} |
|||
|
|||
label { |
|||
svg { |
|||
width: 85px; |
|||
height: 85px; |
|||
} |
|||
|
|||
svg[data-icon='ltc'] { |
|||
margin-right: 10px; |
|||
|
|||
g { |
|||
transform: scale(1.75) translate(-5px, -5px); |
|||
} |
|||
} |
|||
} |
|||
|
|||
input[type=text] { |
|||
width: 100px; |
|||
font-size: 180px; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
} |
|||
} |
|||
|
|||
.inputContainer { |
|||
position: relative; |
|||
width: 100%; |
|||
padding: 40px 0; |
|||
cursor: pointer; |
|||
|
|||
.info { |
|||
margin-bottom: 10px; |
|||
min-height: 19px; |
|||
} |
|||
|
|||
.paymentIcon { |
|||
position: absolute; |
|||
width: 20%; |
|||
left: calc(-12.5% - 75px); |
|||
top: 42px; |
|||
color: $main; |
|||
font-size: 50px; |
|||
text-align: center; |
|||
|
|||
span { |
|||
text-transform: uppercase; |
|||
display: block; |
|||
font-size: 12px; |
|||
font-weight: 200; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.input { |
|||
display: flex; |
|||
justify-content: center; |
|||
font-size: 18px; |
|||
height: auto; |
|||
min-height: 55px; |
|||
border: 1px solid $traditionalgrey; |
|||
border-radius: 6px; |
|||
position: relative; |
|||
padding: 0 20px; |
|||
|
|||
label, input[type=text] { |
|||
font-size: inherit; |
|||
} |
|||
|
|||
label { |
|||
padding-top: 19px; |
|||
padding-bottom: 12px; |
|||
color: $traditionalgrey; |
|||
} |
|||
|
|||
input[type=text] { |
|||
width: 100%; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
height: 55px; |
|||
padding: 0 10px; |
|||
} |
|||
} |
|||
|
|||
.buttonGroup { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: row; |
|||
border-radius: 6px; |
|||
overflow: hidden; |
|||
|
|||
.button { |
|||
cursor: pointer; |
|||
height: 55px; |
|||
min-height: 55px; |
|||
text-transform: none; |
|||
font-size: 18px; |
|||
transition: opacity .2s ease-out; |
|||
background: $main; |
|||
color: $white; |
|||
border: none; |
|||
font-weight: 500; |
|||
padding: 0; |
|||
width: 100%; |
|||
text-align: center; |
|||
line-height: 55px; |
|||
|
|||
&:first-child { |
|||
border-right: 1px solid lighten($main, 20%); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
import Pay from './Pay' |
|||
|
|||
export default Pay |
@ -0,0 +1,68 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import CurrencyIcon from '../../../../../../../components/CurrencyIcon' |
|||
import styles from './Request.scss' |
|||
|
|||
const Request = ({ |
|||
amount, |
|||
setAmount, |
|||
setMessage, |
|||
createInvoice, |
|||
message, |
|||
currentTicker, |
|||
currency, |
|||
crypto, |
|||
close |
|||
}) => { |
|||
const requestClicked = () => { |
|||
createInvoice(amount, message, currency, currentTicker.price_usd) |
|||
close() |
|||
} |
|||
|
|||
return ( |
|||
<div className={styles.container}> |
|||
<section className={styles.amountContainer}> |
|||
<label htmlFor='amount'> |
|||
<CurrencyIcon currency={currency} crypto={crypto} /> |
|||
</label> |
|||
<input |
|||
type='text' |
|||
size='' |
|||
style={{ width: `${amount.length > 1 ? (amount.length * 15) - 5 : 25}%`, fontSize: `${190 - (amount.length ** 2)}px` }} |
|||
value={amount} |
|||
onChange={event => setAmount(event.target.value)} |
|||
id='amount' |
|||
/> |
|||
</section> |
|||
<section className={styles.inputContainer}> |
|||
<label htmlFor='paymentRequest'>Request:</label> |
|||
<input |
|||
type='text' |
|||
placeholder='Dinner, Rent, etc' |
|||
value={message} |
|||
onChange={event => setMessage(event.target.value)} |
|||
id='paymentRequest' |
|||
/> |
|||
</section> |
|||
<section className={styles.buttonGroup}> |
|||
<div className={styles.button} onClick={requestClicked}> |
|||
Request |
|||
</div> |
|||
</section> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
Request.propTypes = { |
|||
amount: PropTypes.string.isRequired, |
|||
setAmount: PropTypes.func.isRequired, |
|||
setMessage: PropTypes.func.isRequired, |
|||
createInvoice: PropTypes.func.isRequired, |
|||
message: PropTypes.string.isRequired, |
|||
currentTicker: PropTypes.object.isRequired, |
|||
currency: PropTypes.string.isRequired, |
|||
crypto: PropTypes.string.isRequired, |
|||
close: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default Request |
@ -0,0 +1,110 @@ |
|||
@import '../../../../../../../variables.scss'; |
|||
|
|||
.container { |
|||
margin: 0 auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 75vh; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.amountContainer { |
|||
color: $main; |
|||
display: flex; |
|||
justify-content: center; |
|||
min-height: 120px; |
|||
margin-bottom: 20px; |
|||
|
|||
label, input[type=text] { |
|||
color: inherit; |
|||
display: inline-block; |
|||
vertical-align: top; |
|||
padding: 0; |
|||
} |
|||
|
|||
label { |
|||
svg { |
|||
width: 85px; |
|||
height: 85px; |
|||
} |
|||
|
|||
svg[data-icon='ltc'] { |
|||
margin-right: 10px; |
|||
|
|||
g { |
|||
transform: scale(1.75) translate(-5px, -5px); |
|||
} |
|||
} |
|||
} |
|||
|
|||
input[type=text] { |
|||
width: 100px; |
|||
font-size: 180px; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
} |
|||
} |
|||
|
|||
.inputContainer { |
|||
width: 100%; |
|||
display: flex; |
|||
justify-content: center; |
|||
font-size: 18px; |
|||
height: auto; |
|||
min-height: 55px; |
|||
margin-bottom: 20px; |
|||
border: 1px solid $traditionalgrey; |
|||
border-radius: 6px; |
|||
position: relative; |
|||
padding: 0 20px; |
|||
|
|||
label, input[type=text] { |
|||
font-size: inherit; |
|||
} |
|||
|
|||
label { |
|||
padding-top: 19px; |
|||
padding-bottom: 12px; |
|||
color: $traditionalgrey; |
|||
} |
|||
|
|||
input[type=text] { |
|||
width: 100%; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
height: 55px; |
|||
padding: 0 10px; |
|||
} |
|||
} |
|||
|
|||
.buttonGroup { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: row; |
|||
border-radius: 6px; |
|||
overflow: hidden; |
|||
|
|||
.button { |
|||
cursor: pointer; |
|||
height: 55px; |
|||
min-height: 55px; |
|||
text-transform: none; |
|||
font-size: 18px; |
|||
transition: opacity .2s ease-out; |
|||
background: $main; |
|||
color: $white; |
|||
border: none; |
|||
font-weight: 500; |
|||
padding: 0; |
|||
width: 100%; |
|||
text-align: center; |
|||
line-height: 55px; |
|||
|
|||
&:first-child { |
|||
border-right: 1px solid lighten($main, 20%); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
import Request from './Request' |
|||
|
|||
export default Request |
@ -0,0 +1,42 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { MdClose } from 'react-icons/lib/md' |
|||
import SuccessfulSendCoins from './SuccessfulSendCoins' |
|||
import styles from './ModalRoot.scss' |
|||
|
|||
const MODAL_COMPONENTS = { |
|||
SUCCESSFUL_SEND_COINS: SuccessfulSendCoins |
|||
/* other modals */ |
|||
} |
|||
|
|||
const ModalRoot = ({ modalType, modalProps, hideModal, currentTicker, currency }) => { |
|||
if (!modalType) { return null } |
|||
|
|||
const SpecificModal = MODAL_COMPONENTS[modalType] |
|||
return ( |
|||
<div className={styles.container}> |
|||
<div className={styles.content}> |
|||
<div className={styles.esc} onClick={hideModal}> |
|||
<MdClose /> |
|||
</div> |
|||
|
|||
<SpecificModal |
|||
{...modalProps} |
|||
hideModal={hideModal} |
|||
currentTicker={currentTicker} |
|||
currency={currency} |
|||
/> |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
ModalRoot.propTypes = { |
|||
modalType: PropTypes.string, |
|||
modalProps: PropTypes.object.isRequired, |
|||
hideModal: PropTypes.func.isRequired, |
|||
currentTicker: PropTypes.object.isRequired, |
|||
currency: PropTypes.string.isRequired |
|||
} |
|||
|
|||
export default ModalRoot |
@ -0,0 +1,42 @@ |
|||
@import '../../../../../variables.scss'; |
|||
|
|||
.container { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: 10; |
|||
background: #fff; |
|||
} |
|||
|
|||
.content { |
|||
position: relative; |
|||
height: 100vh; |
|||
margin: 5%; |
|||
} |
|||
|
|||
.esc { |
|||
position: absolute; |
|||
top: 0; |
|||
right: 0; |
|||
color: $darkestgrey; |
|||
cursor: pointer; |
|||
padding: 20px; |
|||
border-radius: 50%; |
|||
|
|||
&:hover { |
|||
color: $bluegrey; |
|||
background: $darkgrey; |
|||
} |
|||
|
|||
&:active { |
|||
color: $white; |
|||
background: $main; |
|||
} |
|||
|
|||
svg { |
|||
width: 32px; |
|||
height: 32px; |
|||
} |
|||
} |
@ -0,0 +1,40 @@ |
|||
import { shell } from 'electron' |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import AnimatedCheckmark from '../../../../../../components/AnimatedCheckmark' |
|||
import { btc } from '../../../../../../utils' |
|||
import styles from './SuccessfulSendCoins.scss' |
|||
|
|||
const SuccessfulSendCoins = ({ amount, addr, txid, hideModal, currentTicker, currency }) => { |
|||
const calculatedAmount = currency === 'usd' ? btc.satoshisToUsd(amount, currentTicker.price_usd) : btc.satoshisToBtc(amount) |
|||
|
|||
return ( |
|||
<div className={styles.container}> |
|||
<AnimatedCheckmark /> |
|||
<h1> |
|||
You |
|||
<span className={styles.link} onClick={() => shell.openExternal(`https://testnet.smartbit.com.au/tx/${txid}`)}>sent</span> |
|||
<span className={styles.amount}>{calculatedAmount} {currency.toUpperCase()}</span> |
|||
to |
|||
<span className={styles.addr}>{addr}</span> |
|||
</h1> |
|||
<div className={styles.button} onClick={hideModal}> |
|||
Done |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
SuccessfulSendCoins.propTypes = { |
|||
amount: PropTypes.oneOfType([ |
|||
PropTypes.number, |
|||
PropTypes.string |
|||
]).isRequired, |
|||
addr: PropTypes.string.isRequired, |
|||
txid: PropTypes.string.isRequired, |
|||
hideModal: PropTypes.func.isRequired, |
|||
currentTicker: PropTypes.object.isRequired, |
|||
currency: PropTypes.string.isRequired |
|||
} |
|||
|
|||
export default SuccessfulSendCoins |
@ -0,0 +1,37 @@ |
|||
@import '../../../../../../variables.scss'; |
|||
|
|||
.container { |
|||
position: relative; |
|||
min-height: 250px; |
|||
top: calc(50% - 250px); |
|||
text-align: center; |
|||
|
|||
h1 { |
|||
font-size: 20px; |
|||
margin: 50px 0; |
|||
|
|||
.link { |
|||
cursor: pointer; |
|||
color: $main; |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
.amount, .addr { |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.button { |
|||
text-align: center; |
|||
border-radius: 8px; |
|||
background: $main; |
|||
padding: 20px 10px; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
text-transform: uppercase; |
|||
letter-spacing: .2px; |
|||
color: $white; |
|||
width: 15%; |
|||
margin: 0 auto; |
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
import SuccessfulSendCoins from './SuccessfulSendCoins' |
|||
|
|||
export default SuccessfulSendCoins |
@ -0,0 +1,3 @@ |
|||
import ModalRoot from './ModalRoot' |
|||
|
|||
export default ModalRoot |
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,5 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" version="1.1" width="100" height="100"> |
|||
<g id="surface1"> |
|||
<path style="" class="thunderstorm-path" d="M 26 5 C 21.890625 5 18.4375 7.535156 16.90625 11.09375 C 16.605469 11.0625 16.3125 11 16 11 C 11.792969 11 8.320313 13.925781 7.34375 17.84375 C 4.210938 19.253906 2 22.351563 2 26 C 2 30.957031 6.042969 35 11 35 L 16.125 35 L 15.0625 37.625 L 14.53125 39 L 20.5625 39 L 18.0625 45.65625 L 16.9375 48.625 L 19.5625 46.8125 L 32.5625 37.90625 L 33 37.59375 L 33 36 L 28.71875 36 L 29.28125 35 L 39 35 C 43.957031 35 48 30.957031 48 26 C 48 22.417969 45.851563 19.382813 42.8125 17.9375 C 42.292969 13.710938 38.910156 10.433594 34.625 10.125 C 32.90625 7.097656 29.726563 5 26 5 Z M 26 7 C 29.148438 7 31.847656 8.804688 33.15625 11.4375 L 33.4375 12 L 34.0625 12 C 37.792969 12.023438 40.777344 14.941406 40.96875 18.625 L 41 19.28125 L 41.59375 19.5 C 44.164063 20.535156 46 23.046875 46 26 C 46 29.878906 42.878906 33 39 33 L 30.375 33 L 32.875 28.5 L 33.6875 27 L 19.3125 27 L 19.0625 27.625 L 16.90625 33 L 11 33 C 7.121094 33 4 29.878906 4 26 C 4 23.007813 5.871094 20.476563 8.5 19.46875 L 9.03125 19.28125 L 9.125 18.71875 C 9.726563 15.464844 12.5625 13 16 13 C 16.433594 13 16.855469 13.046875 17.28125 13.125 L 18.15625 13.28125 L 18.40625 12.46875 C 19.46875 9.300781 22.460938 7 26 7 Z M 20.6875 29 L 30.28125 29 L 26.125 36.5 L 25.3125 38 L 28.90625 38 L 21.03125 43.40625 L 22.9375 38.34375 L 23.4375 37 L 17.5 37 Z "/> |
|||
</g> |
|||
</svg> |
Loading…
Reference in new issue