Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

74 add spinner to create billing agreement #86

Merged
merged 33 commits into from Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5829c4e
Merge pull request #6 from AgileVentures/code_of_conduct
mattwr18 Jan 9, 2019
3adede1
Add UsersList container, test (#7)
mattwr18 Jan 9, 2019
0ef337a
semantic-ui assets (#13)
dkuku Jan 9, 2019
77d3fab
Install semantic ui (#14)
dkuku Jan 9, 2019
e7947ff
Homepage (#15)
dkuku Jan 9, 2019
6987a27
9 add user and pagination components (#16)
mattwr18 Jan 9, 2019
2c49c78
Add initial readme instructions (#11)
Felistas Jan 10, 2019
b726af1
Sign up page, tests
mattwr18 Jan 13, 2019
12bc189
Update submit button value
mattwr18 Jan 13, 2019
99baa19
Remove package-lock.json
joaopapereira Jan 13, 2019
d072d10
Correct README formatting
joaopapereira Jan 13, 2019
4d21e34
Merge pull request #29 from AgileVentures/random-changes
FedericoEsparza Jan 13, 2019
64431f1
Add standardjs (#31)
joaopapereira Jan 14, 2019
a01bd15
Update endpoints, camelize, add password type
mattwr18 Jan 14, 2019
a2c18ca
Merge branch 'develop' of github.com:AgileVentures/WebsiteOne-FE into…
mattwr18 Jan 15, 2019
1a892bf
Apply standard fixes
mattwr18 Jan 15, 2019
2946477
Move test files, add newlines
mattwr18 Jan 15, 2019
a951a8f
Start with PayPalRecurring
mattwr18 Jan 15, 2019
83367ba
Configure paypal recurring
mattwr18 Jan 21, 2019
f725596
Attempt to execute billing agreement
mattwr18 Jan 21, 2019
d02ac92
Try using paypal-rest-sdk
mattwr18 Jan 22, 2019
361e31e
Start paypal api integration with rails backend
mattwr18 Feb 3, 2019
f34c641
Merge branch 'develop' of github.com:AgileVentures/WebsiteOne-FE into…
mattwr18 Feb 4, 2019
5033499
Set up basic functionality to pay via Paypal
mattwr18 Feb 7, 2019
ce2f473
Upgrade to React 16.8, refactor Subscriptions
mattwr18 Feb 7, 2019
fc94c26
Start styling for PayPalSuccess
mattwr18 Feb 7, 2019
8777cad
Add tests, tweak implementation
mattwr18 Feb 10, 2019
3c4e7fb
Add spinner to Subscriptions component
mattwr18 Feb 10, 2019
bd84e24
Handle errors in create/execute billing agreement
mattwr18 Feb 11, 2019
03faf9e
Extract types, get tests passing
mattwr18 Feb 12, 2019
17a99eb
Make tests more robust
mattwr18 Feb 12, 2019
38a2814
Merge branch 'develop' of github.com:AgileVentures/WebsiteOne-FE into…
mattwr18 Feb 15, 2019
f8a68fb
Extract membership info as helper function, use in PayPalSuccess
mattwr18 Feb 15, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions README.MD
Expand Up @@ -27,6 +27,7 @@ Run tests
```
$ yarn test
```

# Rebuild the semantic UI asserts
## This command needs to be run with npm - yarn does not support interactive prompt installs
`# npm install --save-dev semantic-ui`
Expand All @@ -45,8 +46,6 @@ and copy the folder to our src folder

`cp -R dist/* ../src/assets/`

----

### [Code of Conduct](./CODE_OF_CONDUCT).
### [Contribution Guide](./CONTRIBUTION_GUIDE).

Expand Down
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -28,18 +28,19 @@
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"global": "^4.3.2",
"izitoast": "^1.4.0",
"paypal-checkout": "^4.0.254",
"query-string": "^6.2.0",
"react": "16.8.0",
"react-cookie": "^3.0.8",
"react-dom": "16.8.0",
"react-loading-overlay": "^1.0.1",
"react-redux": "^6.0.0",
"react-router-dom": "^4.3.1",
"react-select": "^2.3.0",
"react-spinners": "^0.5.1",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"semantic-ui-react": "^0.84.0"
"semantic-ui-react": "^0.84.0",
"url": "^0.11.0"
},
"devDependencies": {
"babel-core": "^6.26.3",
Expand Down
24 changes: 24 additions & 0 deletions src/actions/createBillingAgreement.js
@@ -0,0 +1,24 @@
import axios from 'axios'
import { CREATE_BILLING_AGREEMENT_FAILURE } from '../types'

export default (cookies, id, dispatch) => event => {
event.preventDefault()
return axios({
method: 'POST',
timeout: 30000,
url: '/paypal/new.json',
data: {
plan: id
},
headers: {
Authorization: cookies.get('_WebsiteOne_session')
}
})
.then(response => window.location.assign(response.data.redirect_url))
.catch(error => {
dispatch({
type: CREATE_BILLING_AGREEMENT_FAILURE,
message: error.message
})
})
}
23 changes: 23 additions & 0 deletions src/actions/executeBillingAgreement.js
@@ -0,0 +1,23 @@
import axios from 'axios'
import { EXECUTE_BILLING_AGREEMENT_FAILURE } from '../types'

export default (cookies, params, dispatch) => {
return axios({
method: 'GET',
timeout: 20000,
url: '/paypal/create',
params: {
plan: params.plan,
token: params.token
},
headers: {
Authorization: cookies.get('_WebsiteOne_session')
}
})
.catch(error => {
dispatch({
type: EXECUTE_BILLING_AGREEMENT_FAILURE,
message: error.message
})
})
}
4 changes: 2 additions & 2 deletions src/components/PayPalAgreementNew.js
@@ -1,10 +1,10 @@
import React from 'react'
import { Segment, Header } from 'semantic-ui-react'

export default ({ cookies, createBillingAgreement, plan }) => (
export default ({ cookies, createBillingAgreement, setLoading, plan, dispatch }) => (
<Segment padded='very' className='paypal-section' raised>
<Header as='h5'>Get {plan.name} via Paypal:</Header>
<form onSubmit={createBillingAgreement(cookies, plan.id)}>
<form onClick={setLoading} onSubmit={createBillingAgreement(cookies, plan.id, dispatch)}>
<input
type='image'
name='submit'
Expand Down
48 changes: 30 additions & 18 deletions src/components/PayPalSuccess.js
@@ -1,38 +1,50 @@
import React, { useEffect, Fragment } from 'react'
import React, { useEffect, Fragment, useState } from 'react'
import { connect } from 'react-redux'
import executeBillingAgreement from '../helpers/executeBillingAgreement'
import executeBillingAgreement from '../actions/executeBillingAgreement'
import { Header, Container, Segment } from 'semantic-ui-react'
import queryString from 'query-string'
import membership from '../helpers/membershipInfo'
import ErrorBoundary from './ErrorBoundary'
import '../assets/PayPalSuccess.css'

export const PayPalSuccess = props => {
const params = queryString.parse(props.location.search)
const [error, setError] = useState(false)
let name = membership(props, queryString).name
useEffect(() => {
executeBillingAgreement(props, params)
if (props.error.length) {
setError(true)
} else {
executeBillingAgreement(props.cookies, params, props.dispatch)
}
})
return (
<Fragment>
<Container>
<Segment padded='very' className='payment-complete' raised>
<Header as='h2' textAlign='center'>
Thanks, you're now an AgileVentures {}
{params.plan.charAt(0).toUpperCase() + params.plan.slice(1)} Member!
</Header>
<Header as='h4' textAlign='center'>
Your 7 day free trial has now started. Your card will not be charged
until 7 days have passed.
</Header>
<Header as='h5' textAlign='center'>
An AgileVentures mentor will be in touch shortly to help you receive
all of your membership benefits.
</Header>
</Segment>
{!error
? <Segment padded='very' className='payment-complete' raised>
<Header as='h2' textAlign='center'>
Thanks, you're now an AgileVentures {}
{name}{' '}
Member!
</Header>
<Header as='h4' textAlign='center'>
{name === 'Premium' ? 'Your 7 day free trial has now started. Your card will not be charged until 7 days have passed.' : null}
</Header>
<Header as='h5' textAlign='center'>
An AgileVentures mentor will be in touch shortly to help you
receive all of your membership benefits.
</Header>
</Segment> : <ErrorBoundary error />}
</Container>
</Fragment>
)
}

const mapStateToProps = (_, ownProps) => ({ cookies: ownProps.cookies })
const mapStateToProps = (store, ownProps) => ({
cookies: ownProps.cookies,
error: store.error
})
export default connect(
mapStateToProps,
null
Expand Down
92 changes: 51 additions & 41 deletions src/components/Subscriptions.js
@@ -1,69 +1,79 @@
import React, { Fragment, useEffect } from 'react'
import React, { Fragment, useEffect, useState } from 'react'
import { connect } from 'react-redux'
import { setLastLocation } from '../actions/setLastLocationAction'
import { Header, Container, Segment, Grid } from 'semantic-ui-react'
import PayPalAgreementNew from './PayPalAgreementNew'
import createBillingAgreement from '../helpers/createBillingAgreement'
import createBillingAgreement from '../actions/createBillingAgreement'
import queryString from 'query-string'
import membership from '../helpers/membershipInfo'
import LoadingOverlay from 'react-loading-overlay'
import { RingLoader } from 'react-spinners'
import ErrorBoundary from './ErrorBoundary'
import '../assets/Subscriptions.css'

let membership = props => {
let info
let plan = queryString.parse(props.location.search).plan
if (plan === 'premiummob') {
info = { id: 2, name: 'Premium Mob', price: '£25.00' }
} else if (plan === 'premiumf2f') {
info = { id: 3, name: 'Premium F2F', price: '£50.00' }
} else {
info = { id: 1, name: 'Premium', price: '£10.00' }
}
return info
}
export const Subscriptions = props => {
let name = membership(props).name

let name = membership(props, queryString).name
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)
useEffect(() => {
const path = props.location.pathname
const search = props.location.search
props.setLastLocation(path, search)
if (!props.loggedInUser || !props.cookies.get('_WebsiteOne_session')) {
if (!props.cookies.get('_WebsiteOne_session') && !props.loggedInUser.data) {
props.history.push({ pathname: '/login' })
}
if (props.error.length) {
setError(true)
}
})

return (
<Fragment>
<Container>
<Header as='h1'>AgileVentures {name} Membership</Header>
<Header as='h5'>
The price for {name} Membership is {membership(props).price}/Month
</Header>
<Header as='h5'>
{name === 'Premium' ? '7 day free trial! No charge for 7 days' : null}
</Header>
<Grid columns={2} divided className='payment-section'>
<Grid.Row>
<Grid.Column>
<PayPalAgreementNew
cookies={props.cookies}
createBillingAgreement={createBillingAgreement}
plan={membership(props)}
/>
</Grid.Column>
<Grid.Column>
<Segment>
<Header as='h5'>Get {name} via Credit/Debit Card:</Header>
</Segment>
</Grid.Column>
</Grid.Row>
</Grid>
{!error ? <LoadingOverlay
active={loading}
styles={{
overlay: (base) => ({
...base,
background: 'rbg(255, 255, 255, 0.3)'
})
}}
text={<RingLoader sizeUnit={'px'} size={200} color={'#ee7335'} />}
>
<Header as='h1'>AgileVentures {name} Membership</Header>
<Header as='h5'>
The price for {name} Membership is {membership(props, queryString).price}/Month
</Header>
<Header as='h5'>
{name === 'Premium' ? '7 day free trial! No charge for 7 days' : null}
</Header>
<Grid columns={2} divided className='payment-section'>
<Grid.Row>
<Grid.Column>
<PayPalAgreementNew
cookies={props.cookies}
createBillingAgreement={createBillingAgreement}
plan={membership(props, queryString)}
setLoading={setLoading}
dispatch={props.dispatch}
/>
</Grid.Column>
<Grid.Column>
<Segment>
<Header as='h5'>Get {name} via Credit/Debit Card:</Header>
</Segment>
</Grid.Column>
</Grid.Row>
</Grid>
</LoadingOverlay> : <ErrorBoundary error />}
</Container>
</Fragment>
)
}
const mapStateToProps = (store, ownProps) => ({
loggedInUser: store.loggedInUser,
cookies: ownProps.cookies
cookies: ownProps.cookies,
error: store.error
})
export default connect(
mapStateToProps,
Expand Down
4 changes: 1 addition & 3 deletions src/components/User.js
Expand Up @@ -25,9 +25,7 @@ const User = ({ item: user }) => {
</big>
</Link>
<Card.Description>
{user.title_list.length
? user.title_list.map(title => title + ' ')
: null}
{user.title_list.map(title => title + ' ')}
</Card.Description>
<p className='user-card-footer'>
<Icon name='fire' /> {}
Expand Down
12 changes: 12 additions & 0 deletions src/helpers/membershipInfo.js
@@ -0,0 +1,12 @@
export default (props, queryString) => {
let info
let plan = queryString.parse(props.location.search).plan
if (plan === 'premiummob') {
info = { id: 2, name: 'Premium Mob', price: '£25.00' }
} else if (plan === 'premiumf2f') {
info = { id: 3, name: 'Premium F2F', price: '£50.00' }
} else {
info = { id: 1, name: 'Premium', price: '£10.00' }
}
return info
}
2 changes: 1 addition & 1 deletion src/index.js
Expand Up @@ -4,8 +4,8 @@ import { BrowserRouter } from 'react-router-dom'
import { CookiesProvider } from 'react-cookie'
import { Provider } from 'react-redux'
import store from './store'
import './assets/semantic.css'
import App from './components/App'
import './assets/semantic.css'

render(
<CookiesProvider>
Expand Down
12 changes: 10 additions & 2 deletions src/reducers/errorReducer.js
@@ -1,10 +1,18 @@
import { FETCH_PROJECTS_FAILURE } from '../types'
import {
FETCH_PROJECTS_FAILURE,
CREATE_BILLING_AGREEMENT_FAILURE,
EXECUTE_BILLING_AGREEMENT_FAILURE
} from '../types'
import initialState from './initialState'

const errorReducer = (state = initialState.error, action) => {
switch (action.type) {
case FETCH_PROJECTS_FAILURE:
return [ action.message ]
return [action.message]
case CREATE_BILLING_AGREEMENT_FAILURE:
return [action.message]
case EXECUTE_BILLING_AGREEMENT_FAILURE:
return [action.message]
default:
return state
}
Expand Down