mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-29 13:06:03 +10:00
Refactor InboxPage:
use txHasBeenDelivered function, rename css classes, add txIsRequested check and handle unknown transition separately, filter unknown transitions when fetching data, don't render InboxItem if latest transition is unknown, update InboxPage tests.
This commit is contained in:
parent
32fc6ba5b1
commit
6d6ebbffc1
5 changed files with 151 additions and 114 deletions
|
|
@ -331,8 +331,25 @@
|
|||
|
||||
/* Transaction status affects to certain font colors and weights */
|
||||
|
||||
.nameEnquired,
|
||||
.namePending {
|
||||
.stateName {
|
||||
/* This class is empty on purpose, it is used below for banned users */
|
||||
}
|
||||
|
||||
.stateActionNeeded {
|
||||
font-weight: var(--fontWeightSemiBold);
|
||||
color: var(--attentionColor);
|
||||
}
|
||||
|
||||
.stateNoActionNeeded {
|
||||
color: var(--matterColorAnti);
|
||||
}
|
||||
|
||||
.stateSucces {
|
||||
font-weight: var(--fontWeightSemiBold);
|
||||
color: var(--successColor);
|
||||
}
|
||||
|
||||
.nameEmphasized {
|
||||
font-weight: var(--fontWeightBold);
|
||||
|
||||
/* baseline alignment fixes */
|
||||
|
|
@ -340,39 +357,11 @@
|
|||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.stateName {
|
||||
/* This class is empty on purpose, it is used below for banned users */
|
||||
}
|
||||
|
||||
.stateEnquired,
|
||||
.stateRequested,
|
||||
.statePending {
|
||||
font-weight: var(--fontWeightSemiBold);
|
||||
color: var(--attentionColor);
|
||||
}
|
||||
|
||||
.stateAccepted {
|
||||
font-weight: var(--fontWeightSemiBold);
|
||||
color: var(--successColor);
|
||||
}
|
||||
|
||||
.stateCanceled,
|
||||
.stateDeclined,
|
||||
.stateDelivered {
|
||||
color: var(--matterColorAnti);
|
||||
}
|
||||
|
||||
.nameEnquiredOrder,
|
||||
.nameRequested,
|
||||
.nameDeclined,
|
||||
.nameCanceled,
|
||||
.nameAccepted,
|
||||
.nameDelivered {
|
||||
.nameNotEmphasized {
|
||||
font-weight: var(--fontWeightMedium);
|
||||
}
|
||||
|
||||
.bookingEnquired,
|
||||
.bookingPending {
|
||||
.bookingActionNeeded {
|
||||
color: var(--matterColor);
|
||||
margin-top: 4px;
|
||||
|
||||
|
|
@ -381,25 +370,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
.bookingRequested,
|
||||
.bookingCanceled,
|
||||
.bookingDeclined,
|
||||
.bookingAccepted,
|
||||
.bookingDelivered {
|
||||
.bookingNoActionNeeded {
|
||||
color: var(--matterColorAnti);
|
||||
}
|
||||
|
||||
.lastTransitionedAtEnquired,
|
||||
.lastTransitionedAtPending,
|
||||
.lastTransitionedAtRequested {
|
||||
.lastTransitionedAtEmphasized {
|
||||
color: var(--matterColor);
|
||||
font-weight: var(--fontWeightMedium);
|
||||
}
|
||||
|
||||
.lastTransitionedAtCanceled,
|
||||
.lastTransitionedAtAccepted,
|
||||
.lastTransitionedAtDeclined,
|
||||
.lastTransitionedAtDelivered {
|
||||
.lastTransitionedAtNotEmphasized {
|
||||
color: var(--matterColorAnti);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import reverse from 'lodash/reverse';
|
|||
import sortBy from 'lodash/sortBy';
|
||||
import { storableError } from '../../util/errors';
|
||||
import { parse } from '../../util/urlHelpers';
|
||||
import { TRANSITIONS } from '../../util/transaction';
|
||||
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
|
||||
|
||||
const sortedTransactions = txs =>
|
||||
|
|
@ -91,6 +92,7 @@ export const loadData = (params, search) => (dispatch, getState, sdk) => {
|
|||
|
||||
const apiQueryParams = {
|
||||
only: onlyFilter,
|
||||
lastTransitions: TRANSITIONS,
|
||||
include: ['provider', 'provider.profileImage', 'customer', 'customer.profileImage', 'booking'],
|
||||
'fields.image': ['variants.square-small', 'variants.square-small2x'],
|
||||
page,
|
||||
|
|
|
|||
|
|
@ -6,14 +6,12 @@ import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
|||
import moment from 'moment';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
txHasFirstReview,
|
||||
txIsAccepted,
|
||||
txIsCanceled,
|
||||
txIsCompleted,
|
||||
txIsDeclinedOrExpired,
|
||||
txIsEnquired,
|
||||
txIsRequested,
|
||||
txIsReviewed,
|
||||
txHasBeenDelivered,
|
||||
} from '../../util/transaction';
|
||||
import { LINE_ITEM_DAY, LINE_ITEM_UNITS, propTypes } from '../../util/types';
|
||||
import { formatMoney } from '../../util/currency';
|
||||
|
|
@ -55,73 +53,85 @@ const formatDate = (intl, date) => {
|
|||
};
|
||||
|
||||
// Translated name of the state of the given transaction
|
||||
const txState = (intl, tx, isOrder) => {
|
||||
if (txIsAccepted(tx)) {
|
||||
export const txState = (intl, tx, type) => {
|
||||
const isOrder = type === 'order';
|
||||
|
||||
if (txIsEnquired(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameAccepted,
|
||||
bookingClassName: css.bookingAccepted,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtAccepted,
|
||||
stateClassName: css.stateAccepted,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateAccepted',
|
||||
}),
|
||||
};
|
||||
} else if (txIsDeclinedOrExpired(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameDeclined,
|
||||
bookingClassName: css.bookingDeclined,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtDeclined,
|
||||
stateClassName: css.stateDeclined,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateDeclined',
|
||||
}),
|
||||
};
|
||||
} else if (txIsCanceled(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameCanceled,
|
||||
bookingClassName: css.bookingCanceled,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtCanceled,
|
||||
stateClassName: css.stateCanceled,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateCanceled',
|
||||
}),
|
||||
};
|
||||
} else if (txIsCompleted(tx) || txHasFirstReview(tx) || txIsReviewed(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameDelivered,
|
||||
bookingClassName: css.bookingDelivered,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtDelivered,
|
||||
stateClassName: css.stateDelivered,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateDelivered',
|
||||
}),
|
||||
};
|
||||
} else if (txIsEnquired(tx)) {
|
||||
return {
|
||||
nameClassName: isOrder ? css.nameEnquiredOrder : css.nameEnquired,
|
||||
bookingClassName: css.bookingEnquired,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtEnquired,
|
||||
stateClassName: css.stateEnquired,
|
||||
nameClassName: isOrder ? css.nameNotEmphasized : css.nameEmphasized,
|
||||
bookingClassName: css.bookingActionNeeded,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtEmphasized,
|
||||
stateClassName: css.stateActionNeeded,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateEnquiry',
|
||||
}),
|
||||
};
|
||||
} else if (txIsRequested(tx)) {
|
||||
const requested = isOrder
|
||||
? {
|
||||
nameClassName: css.nameNotEmphasized,
|
||||
bookingClassName: css.bookingNoActionNeeded,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtEmphasized,
|
||||
stateClassName: css.stateActionNeeded,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateRequested',
|
||||
}),
|
||||
}
|
||||
: {
|
||||
nameClassName: css.nameEmphasized,
|
||||
bookingClassName: css.bookingActionNeeded,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtEmphasized,
|
||||
stateClassName: css.stateActionNeeded,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.statePending',
|
||||
}),
|
||||
};
|
||||
|
||||
return requested;
|
||||
} else if (txIsDeclinedOrExpired(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameNotEmphasized,
|
||||
bookingClassName: css.bookingNoActionNeeded,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtNotEmphasized,
|
||||
stateClassName: css.stateNoActionNeeded,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateDeclined',
|
||||
}),
|
||||
};
|
||||
} else if (txIsAccepted(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameNotEmphasized,
|
||||
bookingClassName: css.bookingNoActionNeeded,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtNotEmphasized,
|
||||
stateClassName: css.stateSucces,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateAccepted',
|
||||
}),
|
||||
};
|
||||
} else if (txIsCanceled(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameNotEmphasized,
|
||||
bookingClassName: css.bookingNoActionNeeded,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtNotEmphasized,
|
||||
stateClassName: css.stateNoActionNeeded,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateCanceled',
|
||||
}),
|
||||
};
|
||||
} else if (txHasBeenDelivered(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameNotEmphasized,
|
||||
bookingClassName: css.bookingNoActionNeeded,
|
||||
lastTransitionedAtClassName: css.lastTransitionedAtNotEmphasized,
|
||||
stateClassName: css.stateNoActionNeeded,
|
||||
state: intl.formatMessage({
|
||||
id: 'InboxPage.stateDelivered',
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
console.warn('This transition is unknown:', tx.attributes.lastTransition);
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
nameClassName: isOrder ? css.nameRequested : css.namePending,
|
||||
bookingClassName: isOrder ? css.bookingRequested : css.bookingPending,
|
||||
lastTransitionedAtClassName: isOrder
|
||||
? css.lastTransitionedAtRequested
|
||||
: css.lastTransitionedAtPending,
|
||||
stateClassName: isOrder ? css.stateRequested : css.statePending,
|
||||
state: isOrder
|
||||
? intl.formatMessage({
|
||||
id: 'InboxPage.stateRequested',
|
||||
})
|
||||
: intl.formatMessage({
|
||||
id: 'InboxPage.statePending',
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
const bookingData = (unitType, tx, isOrder, intl) => {
|
||||
|
|
@ -174,7 +184,7 @@ BookingInfoMaybe.propTypes = {
|
|||
};
|
||||
|
||||
export const InboxItem = props => {
|
||||
const { unitType, type, tx, intl } = props;
|
||||
const { unitType, type, tx, intl, stateData } = props;
|
||||
const { customer, provider } = tx;
|
||||
const isOrder = type === 'order';
|
||||
|
||||
|
|
@ -185,7 +195,6 @@ export const InboxItem = props => {
|
|||
const isOtherUserBanned = otherUser.attributes.banned;
|
||||
const otherUserDisplayName = userDisplayName(otherUser, bannedUserDisplayName);
|
||||
|
||||
const stateData = txState(intl, tx, isOrder);
|
||||
const isSaleNotification = !isOrder && txIsRequested(tx);
|
||||
const rowNotificationDot = isSaleNotification ? <div className={css.notificationDot} /> : null;
|
||||
const lastTransitionedAt = formatDate(intl, tx.attributes.lastTransitionedAt);
|
||||
|
|
@ -268,11 +277,15 @@ export const InboxPageComponent = props => {
|
|||
const title = isOrders ? ordersTitle : salesTitle;
|
||||
|
||||
const toTxItem = tx => {
|
||||
return (
|
||||
const type = isOrders ? 'order' : 'sale';
|
||||
const stateData = txState(intl, tx, type);
|
||||
|
||||
// Render InboxItem only if the latest transition of the transaction is handled in the `txState` function.
|
||||
return stateData ? (
|
||||
<li key={tx.id.uuid} className={css.listItem}>
|
||||
<InboxItem unitType={unitType} type={isOrders ? 'order' : 'sale'} tx={tx} intl={intl} />
|
||||
<InboxItem unitType={unitType} type={type} tx={tx} intl={intl} stateData={stateData} />
|
||||
</li>
|
||||
);
|
||||
) : null;
|
||||
};
|
||||
|
||||
const error = fetchOrdersOrSalesError ? (
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
createTransaction,
|
||||
createBooking,
|
||||
} from '../../util/test-data';
|
||||
import { InboxPageComponent, InboxItem } from './InboxPage';
|
||||
import { InboxPageComponent, InboxItem, txState } from './InboxPage';
|
||||
import routeConfiguration from '../../routeConfiguration';
|
||||
import { TRANSITION_REQUEST } from '../../util/transaction';
|
||||
import { LINE_ITEM_NIGHT } from '../../util/types';
|
||||
|
|
@ -74,6 +74,8 @@ describe('InboxPage', () => {
|
|||
const ordersTree = renderShallow(<InboxPageComponent {...ordersProps} />);
|
||||
expect(ordersTree).toMatchSnapshot();
|
||||
|
||||
const stateDataOrder = txState(fakeIntl, ordersProps.transactions[0], 'order');
|
||||
|
||||
// Deeply render one InboxItem
|
||||
const orderItem = renderDeep(
|
||||
<InboxItem
|
||||
|
|
@ -81,6 +83,7 @@ describe('InboxPage', () => {
|
|||
type="order"
|
||||
tx={ordersProps.transactions[0]}
|
||||
intl={fakeIntl}
|
||||
stateData={stateDataOrder}
|
||||
/>
|
||||
);
|
||||
expect(orderItem).toMatchSnapshot();
|
||||
|
|
@ -128,6 +131,8 @@ describe('InboxPage', () => {
|
|||
const salesTree = renderShallow(<InboxPageComponent {...salesProps} />);
|
||||
expect(salesTree).toMatchSnapshot();
|
||||
|
||||
const stateDataSale = txState(fakeIntl, salesProps.transactions[0], 'sale');
|
||||
|
||||
// Deeply render one InboxItem
|
||||
const saleItem = renderDeep(
|
||||
<InboxItem
|
||||
|
|
@ -135,6 +140,7 @@ describe('InboxPage', () => {
|
|||
type="sale"
|
||||
tx={salesProps.transactions[0]}
|
||||
intl={fakeIntl}
|
||||
stateData={stateDataSale}
|
||||
/>
|
||||
);
|
||||
expect(saleItem).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -91,6 +91,15 @@ exports[`InboxPage matches snapshot 1`] = `
|
|||
"now": [Function],
|
||||
}
|
||||
}
|
||||
stateData={
|
||||
Object {
|
||||
"bookingClassName": undefined,
|
||||
"lastTransitionedAtClassName": undefined,
|
||||
"nameClassName": undefined,
|
||||
"state": "InboxPage.stateRequested",
|
||||
"stateClassName": undefined,
|
||||
}
|
||||
}
|
||||
tx={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
|
|
@ -216,6 +225,15 @@ exports[`InboxPage matches snapshot 1`] = `
|
|||
"now": [Function],
|
||||
}
|
||||
}
|
||||
stateData={
|
||||
Object {
|
||||
"bookingClassName": undefined,
|
||||
"lastTransitionedAtClassName": undefined,
|
||||
"nameClassName": undefined,
|
||||
"state": "InboxPage.stateRequested",
|
||||
"stateClassName": undefined,
|
||||
}
|
||||
}
|
||||
tx={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
|
|
@ -483,6 +501,15 @@ exports[`InboxPage matches snapshot 3`] = `
|
|||
"now": [Function],
|
||||
}
|
||||
}
|
||||
stateData={
|
||||
Object {
|
||||
"bookingClassName": undefined,
|
||||
"lastTransitionedAtClassName": undefined,
|
||||
"nameClassName": undefined,
|
||||
"state": "InboxPage.statePending",
|
||||
"stateClassName": undefined,
|
||||
}
|
||||
}
|
||||
tx={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
|
|
@ -608,6 +635,15 @@ exports[`InboxPage matches snapshot 3`] = `
|
|||
"now": [Function],
|
||||
}
|
||||
}
|
||||
stateData={
|
||||
Object {
|
||||
"bookingClassName": undefined,
|
||||
"lastTransitionedAtClassName": undefined,
|
||||
"nameClassName": undefined,
|
||||
"state": "InboxPage.statePending",
|
||||
"stateClassName": undefined,
|
||||
}
|
||||
}
|
||||
tx={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue