Fix job creation
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
import errSaga from './err-saga';
|
import errSaga from './err-saga';
|
||||||
import titleSaga from './title-saga';
|
import titleSaga from './title-saga';
|
||||||
|
import localStorageSaga from './local-storage-saga';
|
||||||
|
|
||||||
export default [errSaga, titleSaga];
|
export default [errSaga, titleSaga, localStorageSaga];
|
||||||
|
@ -2,11 +2,12 @@ import {
|
|||||||
saveForm,
|
saveForm,
|
||||||
clearForm,
|
clearForm,
|
||||||
loadSavedForm
|
loadSavedForm
|
||||||
} from '../common/app/routes/Jobs/redux/types';
|
} from '../../common/app/routes/Jobs/redux/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
saveCompleted,
|
||||||
loadSavedFormCompleted
|
loadSavedFormCompleted
|
||||||
} from '../common/app/routes/Jobs/redux/actions';
|
} from '../../common/app/routes/Jobs/redux/actions';
|
||||||
|
|
||||||
const formKey = 'newJob';
|
const formKey = 'newJob';
|
||||||
let enabled = false;
|
let enabled = false;
|
||||||
@ -17,7 +18,7 @@ let store = typeof window !== 'undefined' ?
|
|||||||
try {
|
try {
|
||||||
const testKey = '__testKey__';
|
const testKey = '__testKey__';
|
||||||
store.setItem(testKey, testKey);
|
store.setItem(testKey, testKey);
|
||||||
enabled = store.getItem(testKey) !== testKey;
|
enabled = store.getItem(testKey) === testKey;
|
||||||
store.removeItem(testKey);
|
store.removeItem(testKey);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
enabled = !e;
|
enabled = !e;
|
||||||
@ -35,11 +36,12 @@ export default () => ({ dispatch }) => next => {
|
|||||||
const form = action.payload;
|
const form = action.payload;
|
||||||
try {
|
try {
|
||||||
store.setItem(formKey, JSON.stringify(form));
|
store.setItem(formKey, JSON.stringify(form));
|
||||||
return null;
|
next(action);
|
||||||
} catch (e) {
|
return dispatch(saveCompleted(form));
|
||||||
|
} catch (error) {
|
||||||
return dispatch({
|
return dispatch({
|
||||||
type: 'app.handleError',
|
type: 'app.handleError',
|
||||||
error: new Error('could not parse form data')
|
error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,10 +56,10 @@ export default () => ({ dispatch }) => next => {
|
|||||||
try {
|
try {
|
||||||
const form = JSON.parse(formString);
|
const form = JSON.parse(formString);
|
||||||
return dispatch(loadSavedFormCompleted(form));
|
return dispatch(loadSavedFormCompleted(form));
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
return dispatch({
|
return dispatch({
|
||||||
type: 'app.handleError',
|
type: 'app.handleError',
|
||||||
error: new Error('could not parse form data')
|
error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
|
import { CompositeDisposable } from 'rx';
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import { Button, Input, Col, Row, Well } from 'react-bootstrap';
|
import { Button, Input, Col, Row, Well } from 'react-bootstrap';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { push } from 'react-router-redux';
|
||||||
import PureComponent from 'react-pure-render/component';
|
import PureComponent from 'react-pure-render/component';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
|
import {
|
||||||
|
applyPromo,
|
||||||
|
clearPromo,
|
||||||
|
updatePromo
|
||||||
|
} from '../redux/actions';
|
||||||
|
|
||||||
// real paypal buttons
|
// real paypal buttons
|
||||||
// will take your money
|
// will take your money
|
||||||
const paypalIds = {
|
const paypalIds = {
|
||||||
@ -12,10 +20,14 @@ const paypalIds = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const bindableActions = {
|
const bindableActions = {
|
||||||
|
applyPromo,
|
||||||
|
clearPromo,
|
||||||
|
push,
|
||||||
|
updatePromo
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(
|
||||||
state => state.jobsApp.currentJob,
|
state => state.jobsApp.newJob,
|
||||||
state => state.jobsApp,
|
state => state.jobsApp,
|
||||||
(
|
(
|
||||||
{ id, isHighlighted } = {},
|
{ id, isHighlighted } = {},
|
||||||
@ -46,6 +58,11 @@ const mapStateToProps = createSelector(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export class JobTotal extends PureComponent {
|
export class JobTotal extends PureComponent {
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
this._subscriptions = new CompositeDisposable();
|
||||||
|
}
|
||||||
|
|
||||||
static displayName = 'JobTotal';
|
static displayName = 'JobTotal';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -60,13 +77,15 @@ export class JobTotal extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { jobActions } = this.props;
|
if (!this.props.id) {
|
||||||
jobActions.clearPromo();
|
this.props.push('/jobs');
|
||||||
}
|
}
|
||||||
|
|
||||||
goToJobBoard() {
|
this.props.clearPromo();
|
||||||
const { appActions } = this.props;
|
}
|
||||||
setTimeout(() => appActions.goTo('/jobs'), 0);
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this._subscriptions.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDiscount(discountAmount) {
|
renderDiscount(discountAmount) {
|
||||||
@ -114,7 +133,8 @@ export class JobTotal extends PureComponent {
|
|||||||
promoCode,
|
promoCode,
|
||||||
promoName,
|
promoName,
|
||||||
isHighlighted,
|
isHighlighted,
|
||||||
jobActions
|
applyPromo,
|
||||||
|
updatePromo
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (promoApplied) {
|
if (promoApplied) {
|
||||||
@ -147,7 +167,7 @@ export class JobTotal extends PureComponent {
|
|||||||
md={ 3 }
|
md={ 3 }
|
||||||
mdOffset={ 3 }>
|
mdOffset={ 3 }>
|
||||||
<Input
|
<Input
|
||||||
onChange={ jobActions.setPromoCode }
|
onChange={ updatePromo }
|
||||||
type='text'
|
type='text'
|
||||||
value={ promoCode } />
|
value={ promoCode } />
|
||||||
</Col>
|
</Col>
|
||||||
@ -156,11 +176,12 @@ export class JobTotal extends PureComponent {
|
|||||||
<Button
|
<Button
|
||||||
block={ true }
|
block={ true }
|
||||||
onClick={ () => {
|
onClick={ () => {
|
||||||
jobActions.applyCode({
|
const subscription = applyPromo({
|
||||||
id,
|
id,
|
||||||
code: promoCode,
|
code: promoCode,
|
||||||
type: isHighlighted ? 'isHighlighted' : null
|
type: isHighlighted ? 'isHighlighted' : null
|
||||||
});
|
}).subscribe();
|
||||||
|
this._subscriptions.add(subscription);
|
||||||
}}>
|
}}>
|
||||||
Apply Promo Code
|
Apply Promo Code
|
||||||
</Button>
|
</Button>
|
||||||
@ -176,7 +197,8 @@ export class JobTotal extends PureComponent {
|
|||||||
isHighlighted,
|
isHighlighted,
|
||||||
buttonId,
|
buttonId,
|
||||||
price,
|
price,
|
||||||
discountAmount
|
discountAmount,
|
||||||
|
push
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -239,7 +261,7 @@ export class JobTotal extends PureComponent {
|
|||||||
<form
|
<form
|
||||||
action='https://www.paypal.com/cgi-bin/webscr'
|
action='https://www.paypal.com/cgi-bin/webscr'
|
||||||
method='post'
|
method='post'
|
||||||
onClick={ this.goToJobBoard }
|
onClick={ () => setTimeout(push, 0, '/jobs') }
|
||||||
target='_blank'>
|
target='_blank'>
|
||||||
<input
|
<input
|
||||||
name='cmd'
|
name='cmd'
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { CompositeDisposable, helpers } from 'rx';
|
import { helpers } from 'rx';
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import { push } from 'react-router-redux';
|
||||||
import { reduxForm } from 'redux-form';
|
import { reduxForm } from 'redux-form';
|
||||||
// import debug from 'debug';
|
// import debug from 'debug';
|
||||||
import dedent from 'dedent';
|
import dedent from 'dedent';
|
||||||
@ -17,7 +18,7 @@ import {
|
|||||||
Row
|
Row
|
||||||
} from 'react-bootstrap';
|
} from 'react-bootstrap';
|
||||||
|
|
||||||
import { saveJob } from '../redux/actions';
|
import { saveForm, loadSavedForm } from '../redux/actions';
|
||||||
|
|
||||||
// const log = debug('fcc:jobs:newForm');
|
// const log = debug('fcc:jobs:newForm');
|
||||||
|
|
||||||
@ -106,30 +107,23 @@ function getBsStyle(field) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class NewJob extends React.Component {
|
export class NewJob extends React.Component {
|
||||||
constructor(...args) {
|
|
||||||
super(...args);
|
|
||||||
this._subscriptions = new CompositeDisposable();
|
|
||||||
}
|
|
||||||
|
|
||||||
static displayName = 'NewJob';
|
static displayName = 'NewJob';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
handleSubmit: PropTypes.func,
|
handleSubmit: PropTypes.func,
|
||||||
saveJob: PropTypes.func
|
loadSavedForm: PropTypes.func,
|
||||||
|
push: PropTypes.func,
|
||||||
|
saveForm: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// this.prop.getSavedForm();
|
this.props.loadSavedForm();
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this._subscriptions.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit(job) {
|
handleSubmit(job) {
|
||||||
const subscription = this.props.saveJob(job).subscribe();
|
this.props.saveForm(job);
|
||||||
this._subscriptions.add(subscription);
|
this.props.push('/jobs/new/preview');
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCertClick(name) {
|
handleCertClick(name) {
|
||||||
@ -388,8 +382,10 @@ export default reduxForm(
|
|||||||
fields,
|
fields,
|
||||||
validate: validateForm
|
validate: validateForm
|
||||||
},
|
},
|
||||||
null,
|
state => ({ initialValues: state.jobsApp.initialValues }),
|
||||||
{
|
{
|
||||||
saveJob
|
loadSavedForm,
|
||||||
|
push,
|
||||||
|
saveForm
|
||||||
}
|
}
|
||||||
)(NewJob);
|
)(NewJob);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { CompositeDisposable } from 'rx';
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import { Button, Row, Col } from 'react-bootstrap';
|
import { Button, Row, Col } from 'react-bootstrap';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
@ -7,22 +8,30 @@ import { goBack, push } from 'react-router-redux';
|
|||||||
import ShowJob from './ShowJob.jsx';
|
import ShowJob from './ShowJob.jsx';
|
||||||
import JobNotFound from './JobNotFound.jsx';
|
import JobNotFound from './JobNotFound.jsx';
|
||||||
|
|
||||||
import { clearSavedForm, saveJobToDb } from '../redux/actions';
|
import { clearForm, saveJob } from '../redux/actions';
|
||||||
|
|
||||||
const mapStateToProps = state => ({ job: state.jobsApp.newJob });
|
const mapStateToProps = state => ({ job: state.jobsApp.newJob });
|
||||||
|
|
||||||
const bindableActions = {
|
const bindableActions = {
|
||||||
goBack,
|
goBack,
|
||||||
push,
|
push,
|
||||||
clearSavedForm,
|
clearForm,
|
||||||
saveJobToDb
|
saveJob
|
||||||
};
|
};
|
||||||
|
|
||||||
export class JobPreview extends PureComponent {
|
export class JobPreview extends PureComponent {
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
this._subscriptions = new CompositeDisposable();
|
||||||
|
}
|
||||||
|
|
||||||
static displayName = 'Preview';
|
static displayName = 'Preview';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
job: PropTypes.object
|
job: PropTypes.object,
|
||||||
|
saveJob: PropTypes.func,
|
||||||
|
clearForm: PropTypes.func,
|
||||||
|
push: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -33,8 +42,19 @@ export class JobPreview extends PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this._subscriptions.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleJobSubmit() {
|
||||||
|
const { clearForm, saveJob, job } = this.props;
|
||||||
|
clearForm();
|
||||||
|
const subscription = saveJob(job).subscribe();
|
||||||
|
this._subscriptions.add(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { job, goBack, clearSavedForm, saveJobToDb } = this.props;
|
const { job, goBack } = this.props;
|
||||||
|
|
||||||
if (!job || !job.position || !job.description) {
|
if (!job || !job.position || !job.description) {
|
||||||
return <JobNotFound />;
|
return <JobNotFound />;
|
||||||
@ -54,13 +74,7 @@ export class JobPreview extends PureComponent {
|
|||||||
<Button
|
<Button
|
||||||
block={ true }
|
block={ true }
|
||||||
className='signup-btn'
|
className='signup-btn'
|
||||||
onClick={ () => {
|
onClick={ () => this.handleJobSubmit() }>
|
||||||
clearSavedForm();
|
|
||||||
saveJobToDb({
|
|
||||||
goTo: '/jobs/new/check-out',
|
|
||||||
job
|
|
||||||
});
|
|
||||||
}}>
|
|
||||||
|
|
||||||
Looks great! Let's Check Out
|
Looks great! Let's Check Out
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -10,11 +10,25 @@ export const fetchJobsCompleted = createAction(
|
|||||||
|
|
||||||
export const findJob = createAction(types.findJob);
|
export const findJob = createAction(types.findJob);
|
||||||
|
|
||||||
|
// saves to database
|
||||||
export const saveJob = createAction(types.saveJob);
|
export const saveJob = createAction(types.saveJob);
|
||||||
export const saveJobCompleted = createAction(types.saveJobCompleted);
|
// saves to localStorage
|
||||||
|
|
||||||
export const saveForm = createAction(types.saveForm);
|
export const saveForm = createAction(types.saveForm);
|
||||||
export const clearForm = createAction(types.clearSavedForm);
|
|
||||||
|
export const saveCompleted = createAction(types.saveCompleted);
|
||||||
|
|
||||||
|
export const clearForm = createAction(types.clearForm);
|
||||||
|
|
||||||
|
export const loadSavedForm = createAction(types.loadSavedForm);
|
||||||
export const loadSavedFormCompleted = createAction(
|
export const loadSavedFormCompleted = createAction(
|
||||||
types.loadSavedFormCompleted
|
types.loadSavedFormCompleted
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const clearPromo = createAction(types.clearPromo);
|
||||||
|
export const updatePromo = createAction(
|
||||||
|
types.updatePromo,
|
||||||
|
({ target: { value = '' } = {} } = {}) => value
|
||||||
|
);
|
||||||
|
|
||||||
|
export const applyPromo = createAction(types.applyPromo);
|
||||||
|
export const applyPromoCompleted = createAction(types.applyPromoCompleted);
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Observable } from 'rx';
|
import { Observable } from 'rx';
|
||||||
|
|
||||||
import { testPromo } from './types';
|
import { applyPromo } from './types';
|
||||||
import { applyPromo } from './actions';
|
import { applyPromoCompleted } from './actions';
|
||||||
import { postJSON$ } from '../../../../utils/ajax-stream';
|
import { postJSON$ } from '../../../../utils/ajax-stream';
|
||||||
|
|
||||||
export default () => ({ dispatch }) => next => {
|
export default () => ({ dispatch }) => next => {
|
||||||
return function applyPromoSaga(action) {
|
return function applyPromoSaga(action) {
|
||||||
if (action.type !== testPromo) {
|
if (action.type !== applyPromo) {
|
||||||
return next(action);
|
return next(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ export default () => ({ dispatch }) => next => {
|
|||||||
throw new Error('No promo returned by server');
|
throw new Error('No promo returned by server');
|
||||||
}
|
}
|
||||||
|
|
||||||
return applyPromo(promo);
|
return applyPromoCompleted(promo);
|
||||||
})
|
})
|
||||||
.catch(error => Observable.just({
|
.catch(error => Observable.just({
|
||||||
type: 'app.handleError',
|
type: 'app.handleError',
|
||||||
|
@ -4,6 +4,8 @@ export types from './types';
|
|||||||
|
|
||||||
import fetchJobsSaga from './fetch-jobs-saga';
|
import fetchJobsSaga from './fetch-jobs-saga';
|
||||||
import saveJobSaga from './save-job-saga';
|
import saveJobSaga from './save-job-saga';
|
||||||
|
import applyPromoSaga from './apply-promo-saga';
|
||||||
|
|
||||||
export formNormalizer from './jobs-form-normalizer';
|
export formNormalizer from './jobs-form-normalizer';
|
||||||
|
|
||||||
export const sagas = [ fetchJobsSaga, saveJobSaga ];
|
export const sagas = [ fetchJobsSaga, saveJobSaga, applyPromoSaga ];
|
||||||
|
@ -9,6 +9,8 @@ function replace(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
|
// used by NewJob form
|
||||||
|
initialValues: {},
|
||||||
currentJob: '',
|
currentJob: '',
|
||||||
newJob: {},
|
newJob: {},
|
||||||
jobs: {
|
jobs: {
|
||||||
@ -28,22 +30,26 @@ export default handleActions(
|
|||||||
state.currentJob
|
state.currentJob
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[types.saveJobCompleted]: (state, { payload: newJob }) => {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
newJob
|
|
||||||
};
|
|
||||||
},
|
|
||||||
[types.fetchJobsCompleted]: (state, { payload: { jobs, currentJob } }) => ({
|
[types.fetchJobsCompleted]: (state, { payload: { jobs, currentJob } }) => ({
|
||||||
...state,
|
...state,
|
||||||
currentJob,
|
currentJob,
|
||||||
jobs
|
jobs
|
||||||
}),
|
}),
|
||||||
[types.updatePromoCode]: (state, { payload }) => ({
|
[types.updatePromo]: (state, { payload }) => ({
|
||||||
...state,
|
...state,
|
||||||
promoCode: replace(payload)
|
promoCode: replace(payload)
|
||||||
}),
|
}),
|
||||||
[types.applyPromo]: (state, { payload: promo }) => {
|
[types.saveCompleted]: (state, { payload: newJob }) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
newJob
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[types.loadSavedFormCompleted]: (state, { payload: initialValues }) => ({
|
||||||
|
...state,
|
||||||
|
initialValues
|
||||||
|
}),
|
||||||
|
[types.applyPromoCompleted]: (state, { payload: promo }) => {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
fullPrice: price,
|
fullPrice: price,
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import { Observable } from 'rx';
|
|
||||||
import { push } from 'react-router-redux';
|
import { push } from 'react-router-redux';
|
||||||
|
import { Observable } from 'rx';
|
||||||
|
|
||||||
import { saveJobCompleted } from './actions';
|
import { saveCompleted } from './actions';
|
||||||
import { saveJob } from './types';
|
import { saveJob } from './types';
|
||||||
|
|
||||||
import { handleError } from '../../../redux/types';
|
import { handleError } from '../../../redux/types';
|
||||||
|
|
||||||
export default ({ services }) => ({ dispatch }) => next => {
|
export default ({ services }) => ({ dispatch }) => next => {
|
||||||
return function saveJobSaga(action) {
|
return function saveJobSaga(action) {
|
||||||
|
const result = next(action);
|
||||||
if (action.type !== saveJob) {
|
if (action.type !== saveJob) {
|
||||||
return next(action);
|
return result;
|
||||||
}
|
}
|
||||||
const { payload: job } = action;
|
const { payload: job } = action;
|
||||||
|
|
||||||
@ -19,8 +20,8 @@ export default ({ services }) => ({ dispatch }) => next => {
|
|||||||
})
|
})
|
||||||
.retry(3)
|
.retry(3)
|
||||||
.flatMap(job => Observable.of(
|
.flatMap(job => Observable.of(
|
||||||
saveJobCompleted(job),
|
saveCompleted(job),
|
||||||
push('/jobs/new/preview')
|
push('/jobs/new/check-out')
|
||||||
))
|
))
|
||||||
.catch(error => Observable.just({
|
.catch(error => Observable.just({
|
||||||
type: handleError,
|
type: handleError,
|
||||||
|
@ -4,12 +4,19 @@ const types = [
|
|||||||
|
|
||||||
'findJob',
|
'findJob',
|
||||||
'saveJob',
|
'saveJob',
|
||||||
'saveJobCompleted',
|
|
||||||
|
|
||||||
'saveForm',
|
'saveForm',
|
||||||
|
|
||||||
|
'saveCompleted',
|
||||||
|
|
||||||
'clearForm',
|
'clearForm',
|
||||||
|
|
||||||
'loadSavedForm',
|
'loadSavedForm',
|
||||||
'loadSavedFormCompleted'
|
'loadSavedFormCompleted',
|
||||||
|
|
||||||
|
'clearPromo',
|
||||||
|
'updatePromo',
|
||||||
|
'applyPromo',
|
||||||
|
'applyPromoCompleted'
|
||||||
];
|
];
|
||||||
|
|
||||||
export default types.reduce((types, type) => {
|
export default types.reduce((types, type) => {
|
||||||
|
Reference in New Issue
Block a user