Skip to content

Instantly share code, notes, and snippets.

@RoyalHunt
Created August 20, 2018 11:00
Show Gist options
  • Save RoyalHunt/d5dd182fdb8de9be6edf0b78a076a68c to your computer and use it in GitHub Desktop.
Save RoyalHunt/d5dd182fdb8de9be6edf0b78a076a68c to your computer and use it in GitHub Desktop.
Example for code review
// @flow
import * as React from 'react';
import styled from 'react-emotion';
import { Transition, config, animated } from 'react-spring';
import { compose, lifecycle, branch, renderComponent, withHandlers, pure } from 'recompose';
import { connect } from 'react-redux';
import Swipeable from 'react-swipeable';
import { actions as routerActions } from 'redux-router5';
import { bundleActions, bundleSelectors, bundleThunks } from '@redux/bundle';
import { withRoute } from '@shared';
import type { ItemTypeWithItems } from 'types';
import { mediaMobile } from 'themes';
import { Item, ItemTypeDescription } from './components';
type Props = {
direction: -1 | 1,
currentItemType: ItemTypeWithItems,
onSwipedLeft: Function,
onSwipedRight: Function,
amountOfItemsInBundle: number,
};
const BundleContainer = ({
direction,
currentItemType: { items, ...currentItemTypeRest },
onSwipedLeft,
onSwipedRight,
amountOfItemsInBundle,
}: Props) => (
<Swipeable preventDefaultTouchmoveEvent onSwipedLeft={onSwipedLeft} onSwipedRight={onSwipedRight}>
<Transition
native
config={config.slow}
from={{ transform: `translateX(${direction * 100}%)`, opacity: 0 }}
enter={{ transform: 'translateX(0)', opacity: 1 }}
leave={{ transform: `translateX(${direction * -100}%)`, opacity: 0 }}
>
{style => (
<Container style={style}>
<Wrapper>
{items.map(item => (
<Item
key={item.uuid}
{...item}
amountOfItemsInBundle={amountOfItemsInBundle}
maxRestriction={currentItemTypeRest.max_restriction}
/>
))}
</Wrapper>
</Container>
)}
</Transition>
<ItemTypeDescription amountOfItemsInBundle={amountOfItemsInBundle} {...currentItemTypeRest} />
</Swipeable>
);
const Container = styled(animated.div)`
width: 100%;
position: absolute;
height: ${({ theme }) => `calc(100% - ${theme.header.height})`};
overflow-y: auto;
overflow-x: hidden;
margin-top: 8px;
@media (${mediaMobile}) {
height: 100%;
}
`;
const Wrapper = styled('div')`
width: ${({ theme }) => `calc(100% - ${theme.contextPanel.width})`};
height: fit-content;
padding: 60px 40px;
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: auto;
grid-gap: 20px;
@media (${mediaMobile}) {
width: 100%;
}
`;
const makeMapStateToProps = () => {
const amountOfItemsInBundle = bundleSelectors.amountOfItemsInBundle();
const mapStateToProps = (state, props) => ({
amountOfItemsInBundle: amountOfItemsInBundle(state, props),
direction: bundleSelectors.itemTypesNavigationDirection(state),
currentItemType: bundleSelectors.currentItemType(state),
itemTypes: bundleSelectors.itemTypes(state),
currentItemTypeIndex: bundleSelectors.currentItemTypeIndex(state),
});
return mapStateToProps;
};
const mapDispatchToProps = {
fetchItemTypes: bundleActions.fetchItemTypes,
persistBundle: bundleThunks.persistBundle,
navigateTo: routerActions.navigateTo,
};
export default compose(
withRoute,
connect(
makeMapStateToProps,
mapDispatchToProps
),
lifecycle({
componentDidMount() {
const { route, fetchItemTypes, persistBundle } = this.props;
fetchItemTypes(route.params.bundleUUID);
window.addEventListener('beforeunload', persistBundle);
},
componentWillUnmount() {
const { persistBundle } = this.props;
window.removeEventListener('beforeunload', persistBundle);
},
}),
withHandlers({
onSwipedLeft: ({ navigateTo, currentItemTypeIndex, itemTypes, route }) => () => {
if (currentItemTypeIndex === itemTypes.length - 1) return;
navigateTo('main.menu.bundle-select-items', {
...route.params,
itemTypeUUID: itemTypes[currentItemTypeIndex + 1].uuid,
});
},
onSwipedRight: ({ navigateTo, currentItemTypeIndex, itemTypes, route }) => () => {
if (currentItemTypeIndex === 0) return;
navigateTo('main.menu.bundle-select-items', {
...route.params,
itemTypeUUID: itemTypes[currentItemTypeIndex - 1].uuid,
});
},
}),
branch(({ currentItemType }) => !currentItemType, renderComponent(() => <h1>Loading</h1>)),
pure
)(BundleContainer);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment