Skip to content

Instantly share code, notes, and snippets.

@konstantin24121
Created May 1, 2018 08:38
Show Gist options
  • Save konstantin24121/cd1784015ef03c770004652c743c3816 to your computer and use it in GitHub Desktop.
Save konstantin24121/cd1784015ef03c770004652c743c3816 to your computer and use it in GitHub Desktop.
Container example
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import * as routes from 'config/routes';
import { ACTIONS as authActions } from 'redux/modules/auth';
import { ACTIONS as sitesActions, TYPES as SITES_TYPES } from 'redux/modules/sites';
import { Dropdown, Menu, Avatar, Select, Tooltip } from 'antd';
import { Icon, Link, Indent } from 'components';
import { Root, User, selectStyles } from './UserPanelStyled';
const { Item } = Menu;
const { Option } = Select;
class UserPanel extends React.Component {
componentWillMount() {
this.props.fetchSites();
}
componentWillReceiveProps(nextProps) {
const { location } = nextProps;
if (location.state && location.state.action === SITES_TYPES.setActiveSite) {
this.props.setActiveSite(location.state.siteId);
}
}
handleRedirectAndChangeSite = (siteId) => {
const { history } = this.props;
history.push(routes.MAIN_PAGE.route, { action: SITES_TYPES.setActiveSite, siteId });
}
handleEvent = ({ key }) => {
this.props[key]();
}
renderMenu() {
return (
<Menu onClick={this.handleEvent}>
<Item key="logout">
<Link>
<Icon type="logout" /> Выйти
</Link>
</Item>
</Menu>
);
}
renderSiteSelect = () => {
const { sitesIsLoading, sitesFetchError, sitesList, activeSite } = this.props;
const disableSelect = sitesIsLoading || sitesFetchError;
const value = !disableSelect ? activeSite : undefined;
const emptyList = sitesList.length === 0;
let placeholder = null;
if (sitesIsLoading) {
placeholder = <Icon type="loading" />;
} else if (sitesFetchError) {
placeholder = (
<Tooltip title="Ошибка загрузки списка сайтов">
<Icon type="exclamation-circle" color="error" />
</Tooltip>
);
} else if (emptyList) {
placeholder = 'Нет сайтов';
}
const options = sitesList.map(({
id, url,
}) => (
<Option key={id} value={id} title="">
<Tooltip title={url} placement="left">{url}</Tooltip>
</Option>
));
return (
<Select
defaultActiveFirstOption
placeholder={placeholder}
disabled={disableSelect || emptyList}
showArrow={!disableSelect}
value={emptyList ? undefined : value}
style={selectStyles}
onChange={this.handleRedirectAndChangeSite}
>
{options}
</Select>
);
}
render() {
const { isAuthenticated, userName } = this.props;
if (!isAuthenticated) return null;
const menu = this.renderMenu();
return (
<Root>
{this.renderSiteSelect()}
<Indent left={2} lineHeight={0}>
<Dropdown overlay={menu} trigger={['click']}>
<Link>
<User>
<Indent right={1} lineHeight={0}>
<Avatar icon="user" size="small" />
</Indent>
{userName}
</User>
</Link>
</Dropdown>
</Indent>
</Root>
);
}
}
UserPanel.propTypes = {
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
isAuthenticated: PropTypes.bool.isRequired,
userName: PropTypes.string.isRequired,
sitesIsLoading: PropTypes.bool.isRequired,
sitesFetchError: PropTypes.bool.isRequired,
sitesList: PropTypes.array,
activeSite: PropTypes.number,
logout: PropTypes.func.isRequired,
fetchSites: PropTypes.func.isRequired,
setActiveSite: PropTypes.func.isRequired,
};
const mapStateToProps = (state) => ({
isAuthenticated: state.auth.isAuthenticated,
userName: state.user.userName,
sitesIsLoading: state.sites.isLoading,
sitesFetchError: state.sites.isError,
sitesList: state.sites.list,
activeSite: state.sites.activeId,
});
const actions = {
logout: authActions.logout,
fetchSites: sitesActions.fetchSites,
setActiveSite: sitesActions.setActiveSite,
};
export default withRouter(connect(mapStateToProps, actions)(UserPanel));
import styled, { css } from 'styled-components';
export const Root = styled.div`
display: flex;
justify-content: flex-end;
align-items: center;
`;
const selectStyles = () => ({
width: 170,
});
const applyUserStyles = ({ theme }) => css`
font-size: ${theme.fontSizeBase};
color: ${theme.textColor};
`;
export const User = styled.div`
display: flex;
align-items: center;
${applyUserStyles}
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment