Skip to content

Instantly share code, notes, and snippets.

@aversan
Created December 5, 2017 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aversan/f72a78dfa040ee2f36fc9a096f7b2393 to your computer and use it in GitHub Desktop.
Save aversan/f72a78dfa040ee2f36fc9a096f7b2393 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import shortid from 'shortid';
import Row from 'reactstrap/lib/Row';
import Col from 'reactstrap/lib/Col';
import Input from 'reactstrap/lib/Input';
import FormGroup from 'reactstrap/lib/FormGroup';
import { FULL_MONTH } from '../../../helpers/date';
import { FILTER_PREMIERE, FILTER_ALL } from '../../../actions/active-filter';
import colWidths from '../../../helpers/col-widths';
import Title from '../../../shared/title/title';
import './afisha-header.scss';
const renderOption = item => (
<option key={shortid.generate()} value={item.value}>
{item.name}
</option>
);
class AfishaHeader extends Component {
constructor(props) {
super(props);
this.state = {
currencyMonths: '-1',
currencyGroup: FILTER_ALL,
};
}
onMonthsChange = (event) => {
const { value } = event.target;
this.setState({
currencyMonths: value,
});
this.props.changeFilter({ type: 'month', value: parseInt(value) });
};
onGroupChange = (event) => {
const { value } = event.target;
this.setState({
currencyGroup: value,
});
this.props.changeFilter({ type: 'group', value });
};
render() {
const { className, months } = this.props;
return (
<div
className={classNames('afisha-header', className)}
>
<Row className="align-items-center">
<Col widths={colWidths} xs="12" lg="6" xxl="6">
<Title title="Афиша" as="h1" size={1} page />
</Col>
<Col widths={colWidths} xs="12" md="6" lg="3" xxl="3">
<FormGroup className="mb-md-0 mt-lg-2 mt-xl-3">
<Input
type="select"
className="custom-select w-wide"
onChange={this.onMonthsChange}
value={this.state.currencyMonths}
>
{renderOption({ value: -1, name: 'Месяц' })}
{
months &&
months.map(month =>
renderOption({ value: month, name: FULL_MONTH[month] })
)
}
</Input>
</FormGroup>
</Col>
<Col widths={colWidths} xs="12" md="6" lg="3" xxl="3">
<FormGroup className="mb-md-0 mt-lg-2 mt-xl-3">
<Input
type="select"
className="custom-select w-wide"
onChange={this.onGroupChange}
value={this.state.currencyGroup}
>
{renderOption({ value: FILTER_ALL, name: 'Все спектакли' })}
{renderOption({ value: FILTER_PREMIERE, name: 'Премьеры' })}
</Input>
</FormGroup>
</Col>
</Row>
</div>
);
}
}
AfishaHeader.propTypes = {
months: PropTypes.arrayOf(PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])),
changeFilter: PropTypes.func,
className: PropTypes.string,
};
AfishaHeader.defaultProps = {
months: null,
changeFilter: null,
className: '',
};
export default AfishaHeader;
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import { Provider } from 'react-redux';
import isMobile from 'is-mobile';
import configureStore from './store/configureStore';
import Header from './shared/header/header';
import MainPage from './pages/main-page/container';
import PerformancePage from './pages/performance-page/container';
import ProfilePage from './pages/profile-page/container';
import PerformancesPage from './pages/performances-page/container';
import NewsPage from './pages/news-page/container';
import NewsPostPage from './pages/news-post-page/container';
import CollectivePage from './pages/collective-page/container';
import AfishaPage from './pages/afisha-page/container';
import Layout from './shared/layout/layout';
import LayoutHeader from './shared/layout/layout-header/layout-header';
import Menu from './pages/menu/container';
import './app.scss';
const store = configureStore();
const history = createBrowserHistory();
render(
<Provider store={store}>
<Router history={history}>
<div className={isMobile() ? 'is-mobile' : ''}>
<Layout>
<LayoutHeader element="header">
<Header />
</LayoutHeader>
<Route exact path="/performances/:id" component={PerformancePage} />
<Route exact path="/performances" component={PerformancesPage} />
<Route exact path="/" component={MainPage} />
<Route exact path="/collective" component={CollectivePage} />
<Route exact path="/profiles" component={CollectivePage} />
<Route exact path="/afisha" component={AfishaPage} />
<Route exact path="/articles/:id" component={NewsPostPage} />
<Route exact path="/articles" component={NewsPage} />
</Layout>
<Route exact path="/profiles/:id" component={ProfilePage} />
<Route exact path="/menu" component={Menu} />
</div>
</Router>
</Provider>
,
document.getElementById('react-app-container'),
);
// fonts
@import 'styles/fonts';
// bootstrap base
@import '../node_modules/bootstrap/scss/print';
@import '../node_modules/bootstrap/scss/reboot';
@import '../node_modules/bootstrap/scss/type';
@import '../node_modules/bootstrap/scss/grid';
@import '../node_modules/bootstrap/scss/images';
@import '../node_modules/bootstrap/scss/nav';
@import '../node_modules/bootstrap/scss/forms';
// global
@import 'styles/global';
@import 'styles/forms';
@import 'styles/custom-forms';
// bootstrap utilities
//@import '../node_modules/bootstrap/scss/utilities/align';
//@import '../node_modules/bootstrap/scss/utilities/background';
//@import '../node_modules/bootstrap/scss/utilities/borders';
//@import '../node_modules/bootstrap/scss/utilities/clearfix';
@import '../node_modules/bootstrap/scss/utilities/display';
@import '../node_modules/bootstrap/scss/utilities/embed';
@import '../node_modules/bootstrap/scss/utilities/flex';
//@import '../node_modules/bootstrap/scss/utilities/float';
@import '../node_modules/bootstrap/scss/utilities/position';
@import '../node_modules/bootstrap/scss/utilities/screenreaders';
//@import '../node_modules/bootstrap/scss/utilities/sizing';
@import '../node_modules/bootstrap/scss/utilities/spacing';
@import '../node_modules/bootstrap/scss/utilities/text';
@import '../node_modules/bootstrap/scss/utilities/visibility';
import React from 'react';
import PropTypes from 'prop-types';
import shortid from 'shortid';
import { groupBy, sortBy, uniq } from 'underscore';
import Row from 'reactstrap/lib/Row';
import Col from 'reactstrap/lib/Col';
import { FULL_MONTH, dateDateMonthDayString } from '../../../helpers/date';
import { FILTER_ALL, FILTER_PREMIERE } from '../../../actions/active-filter';
import colWidths from '../../../helpers/col-widths';
import Title from '../../../shared/title/title';
import Lines from '../../../shared/lines/lines';
import AfishaItem from './afisha-item/afisha-item';
const renderItem = item => (
<AfishaItem {...item} key={`item-${shortid.generate()}`} />
);
const renderItems = items => (
<Col widths={colWidths} xs="12" md="9" className="lines-items">
{items.map(item => renderItem(item))}
</Col>
);
const renderDate = (date) => {
const dateTemp = dateDateMonthDayString(new Date(date));
const dateText = dateTemp.split(' ');
return (
<Col widths={colWidths} xs="12" md="3">
<div className="lines-group-date text-uppercase h2 mb-0 py-md-3 d-md-flex flex-md-column flex-lg-row align-items-lg-center">
<span>{dateText[0]} </span>
<span className="typo-sm d-lg-flex flex-lg-column pl-lg-1">
<span>{dateText[1]}</span>
<span className="d-lg-none">, </span>
<span>{dateText[2]}</span>
</span>
</div>
</Col>
);
};
const Afisha = ({ items, setAfishaMonths, activeMonth, activeGroup }) => {
let filteredItems = items;
if (activeMonth && activeMonth !== -1) {
filteredItems = filteredItems.filter(item => new Date(item.releaseDate).getMonth() === activeMonth);
}
if (activeGroup && activeGroup !== FILTER_ALL) {
filteredItems = filteredItems.filter(item => item.premiere && activeGroup === FILTER_PREMIERE);
}
const groups = groupBy(items, 'releaseDate');
const groupKeys = Object.keys(groups);
const filteredGroups = groupBy(filteredItems, 'releaseDate');
const filteredGroupKeys = Object.keys(filteredGroups);
if (groupKeys.length > 0) {
let months = groupKeys.map(date => new Date(date).getMonth());
months = uniq(months);
months = months.sort();
setAfishaMonths(months);
}
return (
<Lines className="afisha">
{
activeMonth &&
FULL_MONTH[activeMonth] &&
<Title title={FULL_MONTH[activeMonth]} as="h3" size={3} uppercase className="lines-group-title d-none d-md-block" />
}
<div className="lines-group-container">
{
(filteredGroupKeys.length > 0) &&
filteredGroupKeys.map(date => (
<Row className="lines-group pb-1 pb-md-0 mb-1 mb-md-0" key={`item-${shortid.generate()}`}>
{renderDate(date)}
{renderItems(sortBy(filteredGroups[date], 'time'))}
</Row>
))
}
</div>
</Lines>
);
};
Afisha.propTypes = {
items: PropTypes.arrayOf(PropTypes.shape),
setAfishaMonths: PropTypes.func,
activeMonth: PropTypes.number,
activeGroup: PropTypes.string,
};
Afisha.defaultProps = {
items: null,
setAfishaMonths: null,
activeMonth: null,
activeGroup: null,
};
export default Afisha;
$x-mobile: map-get($spacers, 2);
$x-desktop: map-get($spacers, 4);
.main-hero {
&-container {
position: relative;
margin-top: -$header-height-breakpoint-desktop;
height: 100vh;
@include media-breakpoint-down(sm) {
margin-top: -$header-height-breakpoint-mobile;
}
}
&-icon-down {
cursor: pointer;
width: 24px;
height: 24px;
position: absolute;
left: 50%;
margin-left: -12px;
bottom: ($header-height-breakpoint-mobile - 1.625rem) / 2;
z-index: 2;
@include media-breakpoint-up(md) {
bottom: ($header-height-breakpoint-desktop - 2.875rem) / 2;
}
.icon {
position: absolute;
left: 50%;
top: 50%;
&-arrow-down {
margin-left: -12px;
margin-top: -6px;
}
}
}
&-image-container {
position: relative;
width: 63%;
@include media-breakpoint-down(xl) {
width: 64.5%;
}
@include media-breakpoint-down(lg) {
width: 66%;
}
@include media-breakpoint-down(md) {
width: calc(100% - #{$x-desktop});
}
@include media-breakpoint-down(sm) {
width: calc(100% + #{2 * $x-mobile});
margin-left: -$x-mobile;
margin-right: -$x-mobile;
}
}
&-logo-container {
width: 100%;
}
&-image.embed-responsive,
&-logo-wrapper.embed-responsive {
padding-top: 56.25%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
height: 0;
}
&-image.embed-responsive,
&-logo-wrapper.embed-responsive {
min-width: 444px;
min-height: 320px;
}
&-logo-1,
&-logo-2 {
position: absolute;
transform: scale(0.75);
@include media-breakpoint-down(xl) {
transform: scale(0.87);
}
@include media-breakpoint-down(lg) {
transform: scale(0.75);
}
@include media-breakpoint-down(md) {
transform: scale(1);
}
@include media-breakpoint-down(sm) {
transform: scale(0.66);
}
&,
& svg {
width: 100%;
height: auto;
}
}
&-logo-1 {
left: 0;
top: 24.5%;
@include media-breakpoint-down(xl) {
top: 22%;
}
@include media-breakpoint-down(lg) {
top: 24%;
}
@include media-breakpoint-down(md) {
top: 18.5%;
}
@include media-breakpoint-down(sm) {
top: 31%;
}
}
&-logo-2 {
right: 0;
bottom: 24.5%;
@include media-breakpoint-down(xl) {
bottom: 22%;
}
@include media-breakpoint-down(lg) {
bottom: 24%;
}
@include media-breakpoint-down(md) {
bottom: 18.5%;
}
@include media-breakpoint-down(sm) {
bottom: 31%;
}
}
}
.main-hero-animated {
&.main-hero-logo-wrapper.embed-responsive {
padding-top: 0;
left: 0;
top: 0;
transform: translate(0, 0);
height: 100vh;
}
&.main-hero-logo-1,
&.main-hero-logo-2 {
width: 362px;
height: $header-height-breakpoint-mobile;
transform: scale(1);
@include media-breakpoint-up(md) {
height: $header-height-breakpoint-desktop;
}
svg {
position: relative;
top: 50%;
transform: translateY(-50%);
}
@include media-breakpoint-down(sm) {
width: 186px;
}
}
&.main-hero-logo-1 {
top: 0;
}
&.main-hero-logo-2 {
bottom: 0;
}
}
.main-hero-animated-finish {
&.main-hero-logo-1,
&.main-hero-logo-2 {
opacity: 0;
}
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Col from 'reactstrap/lib/Col';
import Scroll from 'react-scroll';
import { PerformanceApi, PerformancesApi } from '../../services/api/PerformancesApi';
import { CollectiveApi } from '../../services/api/CollectiveApi';
import { AfishaApi } from '../../services/api/AfishaApi';
import colWidths from '../../helpers/col-widths';
import LayoutBody from '../../shared/layout/layout-body/layout-body';
import LayoutRow from '../../shared/layout/layout-row/layout-row';
import PromoBanner from '../../shared/promo-banner/promo-banner';
import Title from '../../shared/title/title';
import Divider from '../../shared/divider/divider';
import Sidenav from '../../shared/sidenav/sidenav';
import PerformanceInfo from './perfomance-info/perfomance-info';
import Information from './information/information';
import Gallery from './gallery/gallery';
import Collective from './collective/collective';
import Press from './press/press';
import UpcomingDates from './upcoming-dates/upcoming-dates';
import OtherPerformances from './other-perfomances/other-performances';
const ScrollElement = Scroll.Element;
export default class PerformancePage extends Component {
static propTypes = {
name: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
duration: PropTypes.number.isRequired,
directors: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string),
]),
ageLimit: PropTypes.number.isRequired,
image: PropTypes.string,
images: PropTypes.arrayOf(PropTypes.string),
description: PropTypes.string.isRequired,
creativeTeam: PropTypes.arrayOf(PropTypes.shape),
actors: PropTypes.arrayOf(PropTypes.shape),
press: PropTypes.arrayOf(PropTypes.shape),
relatedPerformances: PropTypes.arrayOf(PropTypes.shape),
performanceSchedules: PropTypes.arrayOf(PropTypes.shape),
match: PropTypes.shape(),
setData: PropTypes.func,
};
static defaultProps = {
directors: null,
image: null,
images: null,
creativeTeam: null,
actors: null,
press: null,
relatedPerformances: null,
performanceSchedules: null,
match: null,
setData: null,
};
setData = (id) => {
PerformanceApi.performance(id)
.then((response) => {
const {
name,
title,
duration,
directors,
age_limit,
image,
images,
description,
creative_team,
articles,
actors,
related_performances,
performance_schedules,
} = response;
const data = {
name,
title,
duration,
directors,
ageLimit: age_limit,
image,
images,
description,
creativeTeam: PerformanceApi.formatCreativeTeam(creative_team),
actors: CollectiveApi.formatPerformanceTeam(actors).items,
press: articles,
relatedPerformances: PerformancesApi.formatPerformances(related_performances).items,
performanceSchedules: AfishaApi.formatAfisha(performance_schedules).items,
};
this.props.setData(data);
});
};
componentDidMount() {
const id = parseInt(this.props.match.params.id, 10);
this.setData(id);
}
render() {
const {
name,
title,
duration,
directors,
ageLimit,
image,
description,
images,
creativeTeam,
actors,
press,
performanceSchedules,
relatedPerformances,
} = this.props;
return (
<LayoutBody>
<Sidenav className="d-none d-xl-block" type="performance" />
<Title title={name} as="h1" size={1} page />
<PerformanceInfo title={title} duration={duration} directors={directors} ageLimit={ageLimit} />
<LayoutRow>
<Col widths={colWidths} xs="12" xl="9" className="layout-content ml-auto">
{
image &&
<div>
<Divider type="section" />
<PromoBanner image={image} />
</div>
}
{
description &&
<div>
<Divider type="section" />
<ScrollElement name="information">
<Information description={description} />
</ScrollElement>
</div>
}
{
images &&
<div>
<Divider type="section" />
<Gallery images={images} />
</div>
}
{
(creativeTeam || actors) &&
<div>
<Divider type="section" />
<ScrollElement name="collective">
<Collective creativeTeam={creativeTeam} actors={actors} />
</ScrollElement>
</div>
}
{
press &&
<div>
<Divider type="section" />
<ScrollElement name="press">
<Press items={press} />
</ScrollElement>
</div>
}
{
performanceSchedules &&
<div>
<Divider type="section" />
<ScrollElement name="dates">
<UpcomingDates />
</ScrollElement>
</div>
}
</Col>
</LayoutRow>
{
relatedPerformances &&
<div>
<Divider type="section" />
<OtherPerformances items={relatedPerformances} />
</div>
}
</LayoutBody>
);
}
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Row from 'reactstrap/lib/Row';
import Col from 'reactstrap/lib/Col';
import Input from 'reactstrap/lib/Input';
import FormGroup from 'reactstrap/lib/FormGroup';
import shortid from 'shortid';
import { FILTER_CURRENT, FILTER_PREMIERE, FILTER_SPECIAL, FILTER_ARCHIVE, FILTER_ALL } from '../../../actions/active-filter';
import { filterMap } from './filter-map';
import colWidths from '../../../helpers/col-widths';
import Title from '../../../shared/title/title';
import './performances-header.scss';
const renderCheckbox = (item, onChangeHandler, active) => (
<Col widths={colWidths} xs="3" key={shortid.generate()}>
<label className="custom-control custom-checkbox text-uppercase mb-0 mr-0 d-inline-flex flex-column align-items-center justify-content-center" htmlFor={item.slug}>
<Input
type="checkbox"
className="custom-control-input"
id={item.slug}
value={item.slug}
onChange={onChangeHandler}
checked={active === item.slug}
/>
<span className="custom-control-indicator" />
<span className="custom-control-description d-flex flex-column">
<span>{item.name}</span>
<span className="d-none d-lg-inline">{item.qnt}</span>
</span>
</label>
</Col>
);
const renderOption = item => (
<option key={shortid.generate()} value={item.slug}>
{item.name}
</option>
);
class PerformancesHeader extends Component {
constructor(props) {
super(props);
this.state = {
currency: props.active,
};
}
onSelectChange = (event) => {
const { value } = event.target;
this.setState({
currency: value,
});
this.props.changeActiveFilter(value);
};
onCheckboxChange = (event) => {
const { checked, value } = event.target;
if (checked) {
this.setState({
currency: value,
});
this.props.changeActiveFilter(value);
} else {
this.setState({
currency: FILTER_ALL,
});
this.props.changeActiveFilter(FILTER_ALL);
}
};
render() {
const { categories, className } = this.props;
return (
<div
className={classNames('performances-header text-md-center text-lg-left', className)}
>
<Title title="Репертуар" as="h1" size={1} page />
{
categories &&
<div>
<Row className="d-none d-md-flex">
{
categories.map(item =>
!!item.qnt &&
filterMap.includes(item.slug) &&
renderCheckbox(item, this.onCheckboxChange, this.state.currency)
)
}
</Row>
<Row className="d-md-none">
<Col widths={colWidths} xs="12">
<FormGroup className="mb-0 mt-lg-2 mt-xl-3">
<Input
type="select"
className="custom-select w-wide"
onChange={this.onSelectChange}
value={this.state.currency}
>
{
renderOption({ slug: FILTER_ALL, name: 'Все' })
}
{
categories.map(item =>
!!item.qnt &&
filterMap.includes(item.slug) &&
renderOption(item)
)
}
</Input>
</FormGroup>
</Col>
</Row>
</div>
}
</div>
);
}
}
PerformancesHeader.propTypes = {
categories: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string,
slug: PropTypes.string,
qnt: PropTypes.number,
})),
className: PropTypes.string,
active: PropTypes.oneOf([FILTER_CURRENT, FILTER_PREMIERE, FILTER_SPECIAL, FILTER_ARCHIVE, FILTER_ALL]),
changeActiveFilter: PropTypes.func,
};
PerformancesHeader.defaultProps = {
categories: null,
className: '',
active: FILTER_ALL,
changeActiveFilter: null,
};
export default PerformancesHeader;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import Col from 'reactstrap/lib/Col';
import Row from 'reactstrap/lib/Row';
import { ProfileApi } from '../../services/api/ProfileApi';
import { PerformancesApi } from '../../services/api/PerformancesApi';
import colWidths from '../../helpers/col-widths';
import Header from '../../shared/header/header';
import Title from '../../shared/title/title';
import Divider from '../../shared/divider/divider';
import TextGroup from '../../shared/text-group/text-group';
import Layout from '../../shared/layout/layout';
import LayoutHeader from '../../shared/layout/layout-header/layout-header';
import LayoutBody from '../../shared/layout/layout-body/layout-body';
import LayoutRow from '../../shared/layout/layout-row/layout-row';
import LayoutImage from '../../shared/layout/layout-image/layout-image';
import Movies from './movies/movies';
import Performances from './performances/performances';
export default class ProfilePage extends Component {
static propTypes = {
fullName: PropTypes.string,
categories: PropTypes.arrayOf(PropTypes.string),
image: PropTypes.string,
birthYear: PropTypes.number,
description: PropTypes.string,
performances: PropTypes.arrayOf(PropTypes.shape),
movies: PropTypes.arrayOf(PropTypes.shape),
setData: PropTypes.func,
location: PropTypes.shape(),
match: PropTypes.shape(),
profiles: PropTypes.arrayOf(PropTypes.number),
};
static defaultProps = {
fullName: '',
categories: null,
image: '',
birthYear: 0,
description: '',
performances: null,
movies: null,
setData: null,
showModal: null,
location: null,
match: null,
profiles: null,
};
state = {
visible: true,
from: '',
};
constructor(props) {
super(props);
this.from = (props.location.state && props.location.state.from) ? props.location.state.from : '/';
}
componentDidMount() {
const id = parseInt(this.props.match.params.id, 10);
this.setData(id);
}
setData = (profileId) => {
ProfileApi.profile(profileId)
.then((response) => {
const { performances, movies } = response;
const data = {
...ProfileApi.formatProfile(response),
performances: PerformancesApi.formatPerformances(performances).items,
movies: ProfileApi.formatMovies(movies).items,
};
this.props.setData(data);
});
};
componentWillReceiveProps(nextProps) {
const currentId = parseInt(this.props.match.params.id, 10);
const nextId = parseInt(nextProps.match.params.id, 10);
if (currentId !== nextId) {
this.props.setData(nextId);
}
}
profileClose = () => {
this.setState({ visible: false });
};
render() {
const { fullName, categories, image, description, birthYear, performances, movies, profiles } = this.props;
const { visible } = this.state;
const id = parseInt(this.props.match.params.id, 10);
const currentIndex = profiles && profiles.indexOf(id);
const prevId = profiles && ((currentIndex === 0) ? profiles[profiles.length - 1] : profiles[currentIndex - 1]);
const nextId = profiles && ((currentIndex === profiles.length - 1) ? profiles[0] : profiles[currentIndex + 1]);
if (this.from && !visible) {
return <Redirect to={this.from} />;
} else if (!visible) {
return <Redirect to="/" />;
}
return (
<Layout modal type="profile">
<LayoutHeader>
<Header modal type="profile" prevProfileId={prevId} nextProfileId={nextId} profileClose={this.profileClose} />
</LayoutHeader>
<LayoutBody>
<LayoutRow>
<Col widths={colWidths} xs="12" xl="7" className="layout-content ml-auto">
<Row>
<Col widths={colWidths} xs="12" lg="6" xl="12" className="order-1 text-center text-lg-left">
{
fullName &&
<Title title={fullName} page name className="layout-title mb-xxl-4" />
}
<Row>
<Col widths={colWidths} xs="6">
{
categories &&
<TextGroup title="Категория">
<span>{categories && categories.join(', ')}</span>
</TextGroup>
}
</Col>
<Col widths={colWidths} xs="6">
{
!!birthYear &&
<TextGroup title="Год рождения">
<span>{birthYear}</span>
</TextGroup>
}
</Col>
</Row>
</Col>
<Col widths={colWidths} xs="12" lg="6" xl="12" className="order-3">
{
description &&
<div>
<Divider type="section" />
<div className="profile-text">
{description}
</div>
</div>
}
</Col>
<Col widths={colWidths} xs="12" md="9" lg="6" xl="5" className="order-2 mx-auto layout-image-wrapper">
{
image &&
<div>
<Divider type="section" className="d-lg-none" />
<LayoutImage image={image} />
</div>
}
</Col>
{
performances &&
<Col widths={colWidths} xs="12" className="order-12">
<Divider />
<Performances items={performances} />
</Col>
}
{
movies &&
<Col widths={colWidths} xs="12" className="order-12">
<Movies items={movies} />
</Col>
}
</Row>
</Col>
</LayoutRow>
</LayoutBody>
</Layout>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment