Skip to content

Commit

Permalink
ability to add customer email for invoice #173
Browse files Browse the repository at this point in the history
  • Loading branch information
perminder-klair committed Jun 7, 2019
1 parent 39dc53f commit e0c0397
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 32 deletions.
19 changes: 14 additions & 5 deletions src/components/elements/TextGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ const Hint = styled.p`
width: 90%;
`;

const TextGroup = ({ label, placeholder, error, hint, ...otherProps }) => (
<Field className="field is-horizontal">
<div className="field-label is-normal">
<Label className="label">{label}</Label>
</div>
const TextGroup = ({
label,
placeholder,
error,
hint,
isVertical,
...otherProps
}) => (
<Field className={`field ${isVertical ? '' : 'is-horizontal'}`}>
{label && (
<div className="field-label is-normal">
<Label className="label">{label}</Label>
</div>
)}
<div className="field-body">
<div className="field">
<div className="control">
Expand Down
4 changes: 2 additions & 2 deletions src/config/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default {
debug: process.env.NODE_ENV === 'development',
APP_VERSION: '0.0.1',
siteName: 'Dexpay',
APP_VERSION: '0.0.4',
siteName: 'Dexpay.me',
siteUrl: 'https://dexpay.me',
graphQlUri: 'https://dexpay-api.herokuapp.com/',
// graphQlUri: 'http://localhost:4000/',
Expand Down
39 changes: 22 additions & 17 deletions src/pages/Dashboard/components/RecentPayments/PaymentItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import styled from 'styled-components';
import moment from 'moment';

import { truncateHash } from '../../../../utils/helpers';
import ShareInvoice from './ShareInvoice';
import cryptoIcon from '../../../../assets/dummy/crypto-icon.png';
import FormatCurrency from '../../../../components/FormatCurrency';
import { getCurrencyRates } from '../../../../utils/exchangeRates';

const Container = styled.a`
const Container = styled.div`
padding-left: 1.5rem;
`;
const Content = styled.div`
cursor: pointer;
`;
const Image = styled.img`
margin-top: 6px;
`;
Expand Down Expand Up @@ -49,26 +53,26 @@ class PaymentItem extends React.Component {
const { fiatAmount } = this.state;

return (
<Container
onClick={() => {
if (payment.status === 'pending') {
onOpenModal(payment);
} else {
window.open(
`https://blockscout.com/poa/dai/tx/${payment.txHash}`,
'_blank'
);
}
}}
target="_blank"
className="media"
>
<Container className="media">
<figure className="media-left">
<p className="image is-32x32">
<Image src={cryptoIcon} alt={payment.assetUsed} />
</p>
</figure>
<div className="media-content">
<Content
className="media-content"
onClick={() => {
if (payment.status === 'pending') {
onOpenModal(payment);
} else {
window.open(
`https://blockscout.com/poa/dai/tx/${payment.txHash}`,
'_blank'
);
}
}}
target="_blank"
>
<div className="content">
<p>
<small className="has-text-weight-light">
Expand All @@ -79,11 +83,12 @@ class PaymentItem extends React.Component {
{truncateHash(payment.txHash || '')}
</p>
</div>
</div>
</Content>
<div className="media-right">
<small>
<FormatCurrency currency={currency} value={fiatAmount} />
</small>
<ShareInvoice payment={payment} />
</div>
</Container>
);
Expand Down
22 changes: 14 additions & 8 deletions src/pages/Dashboard/components/RecentPayments/PaymentItemWeb3.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import React from 'react';
import styled from 'styled-components';
import moment from 'moment';

import ShareInvoice from './ShareInvoice';
import { truncateHash } from '../../../../utils/helpers';
import cryptoIcon from '../../../../assets/dummy/crypto-icon.png';
import FormatCurrency from '../../../../components/FormatCurrency';

const Container = styled.a`
const Container = styled.div`
padding-left: 1.5rem;
`;
const Content = styled.div`
cursor: pointer;
`;
const Image = styled.img`
margin-top: 6px;
`;

const PaymentItemWeb3 = ({ payment }) => (
<Container
href={`https://blockscout.com/poa/dai/tx/${payment.transactionHash}`}
target="_blank"
className="media"
>
<Container className="media">
<figure className="media-left">
<p className="image is-32x32">
<Image src={cryptoIcon} alt={payment.currency} />
</p>
</figure>
<div className="media-content">
<Content
className="media-content"
href={`https://blockscout.com/poa/dai/tx/${payment.transactionHash}`}
target="_blank"
>
<div className="content">
<p>
<small className="has-text-weight-light">
Expand All @@ -33,11 +38,12 @@ const PaymentItemWeb3 = ({ payment }) => (
{truncateHash(payment.transactionHash)}
</p>
</div>
</div>
</Content>
<div className="media-right">
<small>
<FormatCurrency value={parseFloat(payment.value)} />
</small>
<ShareInvoice payment={payment} />
</div>
</Container>
);
Expand Down
98 changes: 98 additions & 0 deletions src/pages/Dashboard/components/RecentPayments/ShareInvoice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from 'react';
import styled from 'styled-components';
import Modal from 'react-responsive-modal';
import gql from 'graphql-tag';

import ShareInvoiceForm from './ShareInvoiceForm';
import apolloClient from '../../../../utils/apolloClient';
import dexLogo from '../../../../assets/images/dex-logo-white.png';

const mutation = gql`
mutation updateInvoice($id: ID!, $customerEmail: String!) {
updateInvoice(id: $id, input: { customerEmail: $customerEmail }) {
id
}
}
`;

const Share = styled.div`
text-align: right;
`;

const Header = styled.div`
display: flex;
justify-content: center;
background-color: #000000;
padding: 2rem;
border-radius: 12px 12px 0 0;
`;
const Logo = styled.img`
width: 150px;
height: auto;
`;

const Content = styled.div`
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 3rem;
`;

class ShareInvoice extends React.Component {
state = { isModalOpen: false };

handleSendInvoice = ({ customerEmail }) => {
const { payment } = this.props;
return apolloClient.mutate({
mutation,
variables: { id: payment.id, customerEmail }
});
};

renderModal() {
const { isModalOpen } = this.state;

return (
<Modal
open={isModalOpen}
onClose={() => this.setState({ isModalOpen: false })}
center
showCloseIcon={false}
styles={{
modal: {
maxWidth: 'initial',
width: '600px',
maxHight: '770px',
height: 'auto',
borderRadius: '12px',
padding: 0
}
}}
>
<Header>
<Logo src={dexLogo} alt="Dexpay logo" />
</Header>
<Content>
<p className="is-size-4 has-text-weight-semibold">
Send this transaction details by email
</p>
<ShareInvoiceForm handleUpdate={this.handleSendInvoice} />
</Content>
</Modal>
);
}

render() {
return (
<React.Fragment>
<Share onClick={() => this.setState({ isModalOpen: true })}>
<i className="fas fa-share-alt" />
</Share>
{this.renderModal()}
</React.Fragment>
);
}
}

export default ShareInvoice;
78 changes: 78 additions & 0 deletions src/pages/Dashboard/components/RecentPayments/ShareInvoiceForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withFormik } from 'formik';
import * as yup from 'yup';
import styled from 'styled-components';
import swal from 'sweetalert';

import { TextGroup } from '../../../../components/elements';

const Form = styled.form`
display: flex;
flex-direction: column;
align-items: center;
`;

const ShareInvoiceForm = props => {
const {
values,
errors,
handleChange,
handleBlur,
handleSubmit,
isSubmitting
} = props;

return (
<Form onSubmit={handleSubmit}>
<TextGroup
isVertical
name="customerEmail"
placeholder="Customer email address"
value={values.customerEmail}
onChange={handleChange}
onBlur={handleBlur}
error={errors.customerEmail}
/>
<button
type="submit"
className={`button is-black is-uppercase is-medium ${isSubmitting &&
'is-loading'}`}
>
Send
</button>
</Form>
);
};

ShareInvoiceForm.propTypes = {
values: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired,
handleChange: PropTypes.func.isRequired,
handleBlur: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired
};

export default withFormik({
mapPropsToValues: () => ({
customerEmail: ''
}),
validationSchema: yup.object().shape({
customerEmail: yup
.string()
.required('Wallet Adress is required!')
.email('Invalid email address')
}),
handleSubmit: (values, { setSubmitting, props }) => {
// console.log('handle submit', values, props);
props
.handleUpdate(values)
.then(() => {
swal('Success!', 'Invoice sent successfully!', 'success');
})
.finally(() => {
setSubmitting(false);
});
},
displayName: 'ShareInvoiceForm' // helps with React DevTools
})(ShareInvoiceForm);

0 comments on commit e0c0397

Please sign in to comment.