sdk.transactions.transition reject call + reject button + refactoring

This commit is contained in:
Vesa Luusua 2017-04-28 00:10:54 +03:00
parent 70990f4048
commit 7ce435171c
6 changed files with 78 additions and 10 deletions

View file

@ -1,4 +1,22 @@
.actionButtons,
.actionButtons {
display: flex;
justify-content: space-between;
margin: 1rem 1rem 2rem 1rem;
}
.acceptButton {
}
.rejectButton {
background-color: transparent;
color: #333;
&:enabled:hover {
background-color: transparent;
text-decoration: underline;
}
}
.title {
margin: 1rem 1rem 2rem 1rem;
}

View file

@ -4,16 +4,22 @@ import { fetchCurrentUser } from '../../ducks/user.duck';
// Transition-to keys
const TRANSITION_ACCEPT = 'transition/accept';
const TRANSITION_REJECT = 'transition/reject';
// ================ Action types ================ //
export const FETCH_SALE_REQUEST = 'app/InboxPage/FETCH_SALE_REQUEST';
export const FETCH_SALE_SUCCESS = 'app/InboxPage/FETCH_SALE_SUCCESS';
export const FETCH_SALE_ERROR = 'app/InboxPage/FETCH_SALE_ERROR';
export const FETCH_SALE_REQUEST = 'app/SalePagePage/FETCH_SALE_REQUEST';
export const FETCH_SALE_SUCCESS = 'app/SalePage/FETCH_SALE_SUCCESS';
export const FETCH_SALE_ERROR = 'app/SalePage/FETCH_SALE_ERROR';
export const ACCEPT_SALE_REQUEST = 'app/SalePage/ACCEPT_SALE_REQUEST';
export const ACCEPT_SALE_SUCCESS = 'app/SalePage/ACCEPT_SALE_SUCCESS';
export const ACCEPT_SALE_ERROR = 'app/SalePage/ACCEPT_SALE_ERROR';
export const REJECT_SALE_REQUEST = 'app/SalePage/REJECT_SALE_REQUEST';
export const REJECT_SALE_SUCCESS = 'app/SalePage/REJECT_SALE_SUCCESS';
export const REJECT_SALE_ERROR = 'app/SalePage/REJECT_SALE_ERROR';
export const ACCEPT_SALE_REQUEST = 'app/InboxPage/ACCEPT_SALE_REQUEST';
export const ACCEPT_SALE_SUCCESS = 'app/InboxPage/ACCEPT_SALE_SUCCESS';
export const ACCEPT_SALE_ERROR = 'app/InboxPage/ACCEPT_SALE_ERROR';
// ================ Reducer ================ //
const initialState = {
@ -22,6 +28,7 @@ const initialState = {
transactionRef: null,
acceptOrRejectInProgress: false,
acceptSaleError: null,
rejectSaleError: null,
};
export default function checkoutPageReducer(state = initialState, action = {}) {
@ -45,6 +52,14 @@ export default function checkoutPageReducer(state = initialState, action = {}) {
console.error(payload); // eslint-disable-line
return { ...state, acceptOrRejectInProgress: false, acceptSaleError: payload };
case REJECT_SALE_REQUEST:
return { ...state, acceptOrRejectInProgress: true, rejectSaleError: null };
case REJECT_SALE_SUCCESS:
return { ...state, acceptOrRejectInProgress: false };
case REJECT_SALE_ERROR:
console.error(payload); // eslint-disable-line
return { ...state, acceptOrRejectInProgress: false, rejectSaleError: payload };
default:
return state;
}
@ -60,6 +75,10 @@ const acceptSaleRequest = () => ({ type: ACCEPT_SALE_REQUEST });
const acceptSaleSuccess = () => ({ type: ACCEPT_SALE_SUCCESS });
const acceptSaleError = e => ({ type: ACCEPT_SALE_ERROR, error: true, payload: e });
const rejectSaleRequest = () => ({ type: REJECT_SALE_REQUEST });
const rejectSaleSuccess = () => ({ type: REJECT_SALE_SUCCESS });
const rejectSaleError = e => ({ type: REJECT_SALE_ERROR, error: true, payload: e });
// ================ Thunks ================ //
export const fetchSale = id =>
@ -96,6 +115,23 @@ export const acceptSale = id =>
});
};
export const rejectSale = id =>
(dispatch, getState, sdk) => {
dispatch(rejectSaleRequest());
return sdk.transactions
.transition({ id, transition: TRANSITION_REJECT, params: {} }, { expand: true })
.then(response => {
dispatch(addEntities(response));
dispatch(rejectSaleSuccess());
return response;
})
.catch(e => {
dispatch(rejectSaleError(e));
throw e;
});
};
// loadData is a collection of async calls that need to be made
// before page has all the info it needs to render itself
export const loadData = params =>

View file

@ -6,14 +6,14 @@ import * as propTypes from '../../util/propTypes';
import { ensureBooking, ensureListing, ensureTransaction, ensureUser } from '../../util/data';
import { Button, SaleDetailsPanel, PageLayout } from '../../components';
import { getEntities } from '../../ducks/sdk.duck';
import { acceptSale, loadData } from './SalePage.duck';
import { acceptSale, rejectSale, loadData } from './SalePage.duck';
import css from './SalePage.css';
// SalePage handles data loading
// It show loading data text or SaleDetailsPanel (and later also another panel for messages).
export const SalePageComponent = props => {
const { intl, onAcceptSale, transaction } = props;
const { intl, onAcceptSale, onRejectSale, transaction } = props;
const currentTransaction = ensureTransaction(transaction);
const currentListing = ensureListing(currentTransaction.listing);
const title = currentListing.attributes.title;
@ -38,7 +38,10 @@ export const SalePageComponent = props => {
const actionButtons = currentTransaction.attributes.state === propTypes.TX_STATE_PREAUTHORIZED
? <div className={css.actionButtons}>
<Button onClick={() => onAcceptSale(currentTransaction.id)}>
<Button className={css.rejectButton} onClick={() => onRejectSale(currentTransaction.id)}>
<FormattedMessage id="SalePage.rejectButton" />
</Button>
<Button className={css.acceptButton} onClick={() => onAcceptSale(currentTransaction.id)}>
<FormattedMessage id="SalePage.acceptButton" />
</Button>
</div>
@ -59,6 +62,7 @@ const { func, oneOf } = PropTypes;
SalePageComponent.propTypes = {
intl: intlShape.isRequired,
onAcceptSale: func.isRequired,
onRejectSale: func.isRequired,
tab: oneOf(['details', 'discussion']).isRequired,
transaction: propTypes.transaction,
};
@ -77,6 +81,7 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => {
return {
onAcceptSale: transactionId => dispatch(acceptSale(transactionId)),
onRejectSale: transactionId => dispatch(rejectSale(transactionId)),
};
};

View file

@ -25,6 +25,7 @@ describe('SalePage', () => {
const props = {
onAcceptSale: () => {},
onRejectSale: () => {},
transaction,
tab: 'details',
intl: fakeIntl,

View file

@ -67,6 +67,13 @@ exports[`SalePage matches snapshot 1`] = `
}
} />
<div>
<Button
className={null}
onClick={[Function]}>
<FormattedMessage
id="SalePage.rejectButton"
values={Object {}} />
</Button>
<Button
className={null}
onClick={[Function]}>

View file

@ -71,6 +71,7 @@
"SaleDetailsPanel.saleAcceptedStatus": "You accepted the booking.",
"SaleDetailsPanel.saleRequestedStatus": "{customerName} is waiting for your response.",
"SalePage.acceptButton": "Accept",
"SalePage.rejectButton": "Reject",
"SalePage.loadingData": "Loading sale data.",
"SalePage.title": "Sale details for ${title}.",
"SearchPage.foundResults": "{count, number} {count, plural, one {listing} other {listings}} found.",