mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
commit
b00c3d6bbc
19 changed files with 10734 additions and 513 deletions
|
@ -99,6 +99,7 @@
|
||||||
"redux-persist": "^5.10.0",
|
"redux-persist": "^5.10.0",
|
||||||
"redux-saga": "^1.1.1",
|
"redux-saga": "^1.1.1",
|
||||||
"reduxsauce": "^1.0.0",
|
"reduxsauce": "^1.0.0",
|
||||||
|
"resize-sensor": "^0.0.6",
|
||||||
"sass-loader": "^7.3.1",
|
"sass-loader": "^7.3.1",
|
||||||
"sass-resources-loader": "^2.0.0",
|
"sass-resources-loader": "^2.0.0",
|
||||||
"scrypt": "^6.0.3",
|
"scrypt": "^6.0.3",
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
.blur {
|
.blur {
|
||||||
filter: blur(0);
|
|
||||||
transition: filter 0.25s;
|
|
||||||
will-change: filter;
|
|
||||||
padding-top: $header_height + 2px;
|
padding-top: $header_height + 2px;
|
||||||
display: flex;
|
display: flex;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
41
src/components/containers/Sticky/index.tsx
Normal file
41
src/components/containers/Sticky/index.tsx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import React, { FC, ReactComponentElement, DetailsHTMLAttributes, useEffect, useRef } from 'react';
|
||||||
|
import styles from './styles.scss';
|
||||||
|
import StickySidebar from 'sticky-sidebar';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import ResizeSensor from 'resize-sensor';
|
||||||
|
|
||||||
|
interface IProps extends DetailsHTMLAttributes<HTMLDivElement> {}
|
||||||
|
|
||||||
|
(window as any).StickySidebar = StickySidebar;
|
||||||
|
(window as any).ResizeSensor = ResizeSensor;
|
||||||
|
|
||||||
|
const Sticky: FC<IProps> = ({ children }) => {
|
||||||
|
const ref = useRef(null);
|
||||||
|
let sb = null;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ref.current) return;
|
||||||
|
|
||||||
|
sb = new StickySidebar(ref.current, {
|
||||||
|
resizeSensor: true,
|
||||||
|
topSpacing: 72,
|
||||||
|
bottomSpacing: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => sb.destroy();
|
||||||
|
}, [ref.current, children]);
|
||||||
|
|
||||||
|
if (sb) {
|
||||||
|
sb.updateSticky();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classnames(styles.wrap, 'sidebar_container')}>
|
||||||
|
<div className="sidebar" ref={ref}>
|
||||||
|
<div className={classnames(styles.sticky, 'sidebar__inner')}>{children}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { Sticky };
|
15
src/components/containers/Sticky/styles.scss
Normal file
15
src/components/containers/Sticky/styles.scss
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
.wrap {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
:global(.sidebar) {
|
||||||
|
will-change: min-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.sidebar__inner) {
|
||||||
|
transform: translate(0, 0); /* For browsers don't support translate3d. */
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
will-change: position, transform;
|
||||||
|
}
|
||||||
|
}
|
13
src/components/main/Footer/index.tsx
Normal file
13
src/components/main/Footer/index.tsx
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import React, { FC, memo } from 'react';
|
||||||
|
import styles from './styles.scss';
|
||||||
|
|
||||||
|
interface IProps {}
|
||||||
|
|
||||||
|
const Footer: FC<IProps> = memo(() => (
|
||||||
|
<div className={styles.footer}>
|
||||||
|
<div className={styles.slogan}>Уделяй больше времени тишине. Спасибо</div>
|
||||||
|
<div className={styles.copy}>2009 - {new Date().getFullYear()}</div>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
export { Footer };
|
23
src/components/main/Footer/styles.scss
Normal file
23
src/components/main/Footer/styles.scss
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
font: $font_12_semibold;
|
||||||
|
background: transparentize(black, 0.9);
|
||||||
|
border-radius: 0 0 $radius $radius;
|
||||||
|
align-items: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: darken(white, 80%);
|
||||||
|
padding-top: 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
@include outer_shadow();
|
||||||
|
}
|
||||||
|
|
||||||
|
.slogan {
|
||||||
|
flex: 1;
|
||||||
|
padding: $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy {
|
||||||
|
padding: $gap;
|
||||||
|
}
|
|
@ -6,8 +6,6 @@ import { Switch, Route, Redirect } from 'react-router-dom';
|
||||||
import { history } from '~/redux/store';
|
import { history } from '~/redux/store';
|
||||||
import { FlowLayout } from '~/containers/flow/FlowLayout';
|
import { FlowLayout } from '~/containers/flow/FlowLayout';
|
||||||
import { MainLayout } from '~/containers/main/MainLayout';
|
import { MainLayout } from '~/containers/main/MainLayout';
|
||||||
import { ImageExample } from '~/containers/examples/ImageExample';
|
|
||||||
import { EditorExample } from '~/containers/examples/EditorExample';
|
|
||||||
import { Sprites } from '~/sprites/Sprites';
|
import { Sprites } from '~/sprites/Sprites';
|
||||||
import { URLS } from '~/constants/urls';
|
import { URLS } from '~/constants/urls';
|
||||||
import { Modal } from '~/containers/dialogs/Modal';
|
import { Modal } from '~/containers/dialogs/Modal';
|
||||||
|
@ -39,8 +37,6 @@ const Component: FC<IProps> = ({ modal: { is_shown } }) => {
|
||||||
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path={URLS.BASE} component={FlowLayout} />
|
<Route exact path={URLS.BASE} component={FlowLayout} />
|
||||||
<Route path={URLS.EXAMPLES.IMAGE} component={ImageExample} />
|
|
||||||
<Route path={URLS.EXAMPLES.EDITOR} component={EditorExample} />
|
|
||||||
<Route path={URLS.NODE_URL(':id')} component={NodeLayout} />
|
<Route path={URLS.NODE_URL(':id')} component={NodeLayout} />
|
||||||
<Route path={URLS.BORIS} component={BorisLayout} />
|
<Route path={URLS.BORIS} component={BorisLayout} />
|
||||||
<Route path={URLS.ERRORS.NOT_FOUND} component={ErrorNotFound} />
|
<Route path={URLS.ERRORS.NOT_FOUND} component={ErrorNotFound} />
|
||||||
|
@ -57,7 +53,4 @@ const Component: FC<IProps> = ({ modal: { is_shown } }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps, mapDispatchToProps)(hot(module)(Component));
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(hot(module)(Component));
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
import React, { FC } from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { Card } from '~/components/containers/Card';
|
|
||||||
import * as styles from './styles.scss';
|
|
||||||
import { Group } from '~/components/containers/Group';
|
|
||||||
import { CellGrid } from '~/components/containers/CellGrid';
|
|
||||||
import { Panel } from '~/components/containers/Panel';
|
|
||||||
import { Scroll } from '~/components/containers/Scroll';
|
|
||||||
import { Tags } from '~/components/node/Tags';
|
|
||||||
import { Button } from '~/components/input/Button';
|
|
||||||
import { Filler } from '~/components/containers/Filler';
|
|
||||||
import { InputText } from '~/components/input/InputText';
|
|
||||||
import { Icon } from '~/components/input/Icon';
|
|
||||||
import { Grid } from '~/components/containers/Grid';
|
|
||||||
|
|
||||||
interface IProps {}
|
|
||||||
|
|
||||||
const EditorExample: FC<IProps> = () => (
|
|
||||||
<Card className={styles.wrap} seamless>
|
|
||||||
<Group horizontal className={styles.group} seamless>
|
|
||||||
<div className={styles.editor}>
|
|
||||||
<Panel className={classNames(styles.editor_panel, styles.editor_image_panel)}>
|
|
||||||
<Scroll>
|
|
||||||
<CellGrid className={styles.editor_image_container} size={200}>
|
|
||||||
<div className={styles.editor_image} />
|
|
||||||
<div className={styles.editor_image} />
|
|
||||||
<div className={styles.editor_image} />
|
|
||||||
<div className={styles.editor_image} />
|
|
||||||
</CellGrid>
|
|
||||||
</Scroll>
|
|
||||||
</Panel>
|
|
||||||
|
|
||||||
<Panel>
|
|
||||||
<Grid columns="1fr" stretchy>
|
|
||||||
<Card className={styles.feature_card}>
|
|
||||||
<div className={styles.cover} />
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
</Panel>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.panel}>
|
|
||||||
<Panel>
|
|
||||||
<Group>
|
|
||||||
<InputText title="Заголовок" />
|
|
||||||
|
|
||||||
<Tags
|
|
||||||
tags={[
|
|
||||||
{ title: 'Избранный' },
|
|
||||||
{ title: 'Плейлист' },
|
|
||||||
{ title: 'Просто' },
|
|
||||||
{ title: '+ фото' },
|
|
||||||
{ title: '+ с музыкой' },
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</Group>
|
|
||||||
</Panel>
|
|
||||||
|
|
||||||
<Panel stretchy />
|
|
||||||
|
|
||||||
<Panel>
|
|
||||||
<Button iconRight="play" stretchy>
|
|
||||||
Submit?
|
|
||||||
</Button>
|
|
||||||
</Panel>
|
|
||||||
</div>
|
|
||||||
</Group>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
|
|
||||||
export { EditorExample };
|
|
|
@ -1,87 +0,0 @@
|
||||||
.wrap {
|
|
||||||
align-items: stretch;
|
|
||||||
justify-content: center;
|
|
||||||
display: flex;
|
|
||||||
background: $editor_bg;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch !important;
|
|
||||||
justify-content: stretch;
|
|
||||||
//flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: $editor_panel_bg;
|
|
||||||
flex: 1;
|
|
||||||
border-radius: $radius;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor {
|
|
||||||
flex: 2;
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor_image_panel {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor_image_container {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor_image {
|
|
||||||
background: transparentize(white, 0.95);
|
|
||||||
padding-bottom: 100%;
|
|
||||||
border-radius: $radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature_card {
|
|
||||||
height: 120px;
|
|
||||||
background: darken($main_bg_color, 6%);
|
|
||||||
color: transparentize(white, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font: $font_18_semibold;
|
|
||||||
box-shadow: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cover {
|
|
||||||
border-radius: $radius;
|
|
||||||
background: url("http://37.192.131.144/full/attached/2017/11/f01fdaaea789915284757634baf7cd11.jpg");
|
|
||||||
flex: 1;
|
|
||||||
height: 120px;
|
|
||||||
background-size: cover;
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel_main {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close_icon {
|
|
||||||
height: 24px;
|
|
||||||
width: 24px;
|
|
||||||
background: transparentize(white, 0.95);
|
|
||||||
flex: 0 0 24px;
|
|
||||||
border-radius: $radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
.views {
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
import React, { FC } from 'react';
|
|
||||||
import { Card } from '~/components/containers/Card';
|
|
||||||
import * as styles from './styles.scss';
|
|
||||||
import { Padder } from '~/components/containers/Padder';
|
|
||||||
import { Group } from '~/components/containers/Group';
|
|
||||||
import { InputText } from '~/components/input/InputText';
|
|
||||||
import { Button } from '~/components/input/Button';
|
|
||||||
import { Filler } from '~/components/containers/Filler';
|
|
||||||
import { Icon } from '~/components/input/Icon';
|
|
||||||
|
|
||||||
interface IProps {}
|
|
||||||
|
|
||||||
const HorizontalExample: FC<IProps> = () => (
|
|
||||||
<div className={styles.wrap}>
|
|
||||||
<Card seamless className={styles.card}>
|
|
||||||
<div className={styles.editor}>
|
|
||||||
<div className={styles.uploads}>
|
|
||||||
<div className={styles.cell} />
|
|
||||||
<div className={styles.cell} />
|
|
||||||
<div className={styles.cell} />
|
|
||||||
<div className={styles.cell} />
|
|
||||||
<div className={styles.cell} />
|
|
||||||
<div className={styles.cell} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Padder className={styles.features}>
|
|
||||||
<Group horizontal>
|
|
||||||
<div className={styles.feature_add_btn}>
|
|
||||||
<Icon icon="plus" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.feature}>
|
|
||||||
<Group horizontal>
|
|
||||||
<div>ОБЛОЖКА</div>
|
|
||||||
<Icon icon="close" />
|
|
||||||
</Group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Filler />
|
|
||||||
|
|
||||||
<div className={styles.feature_cell}>
|
|
||||||
<Icon icon="cell-single" size={24} />
|
|
||||||
</div>
|
|
||||||
</Group>
|
|
||||||
</Padder>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Padder className={styles.panel}>
|
|
||||||
<Group horizontal>
|
|
||||||
<InputText title="Название" />
|
|
||||||
|
|
||||||
<Button title="Сохранить" iconRight="check" />
|
|
||||||
</Group>
|
|
||||||
</Padder>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
export { HorizontalExample };
|
|
|
@ -1,91 +0,0 @@
|
||||||
.wrap {
|
|
||||||
flex: 1;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
background: darken($content_bg, 4%);
|
|
||||||
box-shadow: transparentize(black, 0.7) 0 10px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor {
|
|
||||||
background: $content_bg;
|
|
||||||
min-height: 200px;
|
|
||||||
min-width: 50vw;
|
|
||||||
|
|
||||||
border-radius: $radius;
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
justify-content: stretch;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
@include outer_shadow();
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature_add_btn {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 24px;
|
|
||||||
background: $red_gradient;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
background: lighten($content_bg, 4%);
|
|
||||||
padding: $gap $gap $gap 20px;
|
|
||||||
border-radius: 24px;
|
|
||||||
font: $font_14_semibold;
|
|
||||||
height: 40px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature_cell {
|
|
||||||
background: lighten($content_bg, 4%);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border-radius: $radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uploads {
|
|
||||||
flex: 1;
|
|
||||||
padding: $gap;
|
|
||||||
// padding-bottom: 0;
|
|
||||||
display: grid;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
grid-column-gap: $gap;
|
|
||||||
grid-row-gap: $gap;
|
|
||||||
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(30vw, 1fr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell {
|
|
||||||
background: lighten($content_bg, 6%);
|
|
||||||
border-radius: $radius;
|
|
||||||
padding-bottom: 100%;
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
import React, { FC } from 'react';
|
|
||||||
import range from 'ramda/es/range';
|
|
||||||
import { Card } from '~/components/containers/Card';
|
|
||||||
import * as styles from './styles.scss';
|
|
||||||
import { Group } from '~/components/containers/Group';
|
|
||||||
import { Padder } from '~/components/containers/Padder';
|
|
||||||
import { Comment } from '~/components/node/Comment';
|
|
||||||
import { NodePanel } from '~/components/node/NodePanel';
|
|
||||||
import { NodeRelated } from '~/components/node/NodeRelated';
|
|
||||||
import { Tags } from '~/components/node/Tags';
|
|
||||||
import { NodeNoComments } from '~/components/node/NodeNoComments';
|
|
||||||
import { ImageSwitcher } from '~/components/node/ImageSwitcher';
|
|
||||||
|
|
||||||
interface IProps {}
|
|
||||||
|
|
||||||
const ImageExample: FC<IProps> = () => <Card className={styles.node} seamless></Card>;
|
|
||||||
|
|
||||||
export { ImageExample };
|
|
||||||
|
|
||||||
/*
|
|
||||||
<Padder className={styles.buttons}>
|
|
||||||
<Group>
|
|
||||||
<MenuButton title="На главной" description="плывет по течению" icon="star" />
|
|
||||||
|
|
||||||
<MenuButton title="Видно всем" icon="star" />
|
|
||||||
|
|
||||||
<MenuButton title="Редактировать" icon="star" />
|
|
||||||
</Group>
|
|
||||||
</Padder>
|
|
||||||
*/
|
|
|
@ -1,53 +0,0 @@
|
||||||
.image_container {
|
|
||||||
width: 100%;
|
|
||||||
background: $node_image_bg;
|
|
||||||
border-radius: $panel_radius 0 0 $panel_radius;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.image {
|
|
||||||
max-height: 800px;
|
|
||||||
opacity: 1;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: $radius $radius 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
align-items: stretch !important;
|
|
||||||
|
|
||||||
@include vertical_at_tablet;
|
|
||||||
}
|
|
||||||
|
|
||||||
.comments {
|
|
||||||
flex: 3 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
flex: 1 3;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
padding-left: $gap / 2;
|
|
||||||
|
|
||||||
@include tablet {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.node {
|
|
||||||
background: $node_bg;
|
|
||||||
box-shadow: $node_shadow;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image {
|
|
||||||
background: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
background: $node_buttons_bg;
|
|
||||||
flex: 1;
|
|
||||||
border-radius: $panel_radius;
|
|
||||||
box-shadow: $comment_shadow;
|
|
||||||
}
|
|
|
@ -19,6 +19,6 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: $content_width;
|
max-width: $content_width;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-bottom: 64px;
|
padding-bottom: 29px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ import { NodeCommentForm } from '~/components/node/NodeCommentForm';
|
||||||
import * as NODE_ACTIONS from '~/redux/node/actions';
|
import * as NODE_ACTIONS from '~/redux/node/actions';
|
||||||
import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
||||||
import isBefore from 'date-fns/isBefore';
|
import isBefore from 'date-fns/isBefore';
|
||||||
|
import { Card } from '~/components/containers/Card';
|
||||||
|
import { Footer } from '~/components/main/Footer';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
node: selectNode(state),
|
node: selectNode(state),
|
||||||
|
@ -68,58 +70,38 @@ const BorisLayoutUnconnected: FC<IProps> = ({
|
||||||
<div className={styles.caption}>
|
<div className={styles.caption}>
|
||||||
<div className={styles.caption_text}>{title}</div>
|
<div className={styles.caption_text}>{title}</div>
|
||||||
</div>
|
</div>
|
||||||
<img src={boris} />
|
|
||||||
|
<img src={boris} alt="Борис" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.column}>
|
<Card className={styles.content}>
|
||||||
<div className={styles.daygrid}>
|
<Group className={styles.grid}>
|
||||||
<div className={styles.label}>Убежищу сегодня:</div>
|
{is_user && <NodeCommentForm is_before />}
|
||||||
<div className={styles.day}>10</div>
|
|
||||||
<div>лет</div>
|
|
||||||
<div className={styles.day}>2</div>
|
|
||||||
<div>месяца</div>
|
|
||||||
|
|
||||||
<div className={styles.line} />
|
{is_loading_comments ? (
|
||||||
|
<NodeNoComments is_loading />
|
||||||
|
) : (
|
||||||
|
<NodeComments
|
||||||
|
comments={comments}
|
||||||
|
comment_data={comment_data}
|
||||||
|
comment_count={comment_count}
|
||||||
|
user={user}
|
||||||
|
onDelete={nodeLockComment}
|
||||||
|
onEdit={nodeEditComment}
|
||||||
|
onLoadMore={nodeLoadMoreComments}
|
||||||
|
order="ASC"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Group>
|
||||||
|
|
||||||
<div className={styles.label}>Мы собрали:</div>
|
<Footer />
|
||||||
<div className={styles.day}>2374</div>
|
</Card>
|
||||||
<div>поста</div>
|
|
||||||
<div className={styles.day}>14765</div>
|
|
||||||
<div>комментариев</div>
|
|
||||||
<div className={styles.day}>4260</div>
|
|
||||||
<div>файла</div>
|
|
||||||
<div className={styles.day}>54</div>
|
|
||||||
<div>жителя</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Group className={styles.content}>
|
|
||||||
{is_user && <NodeCommentForm is_before />}
|
|
||||||
|
|
||||||
{is_loading_comments ? (
|
|
||||||
<NodeNoComments is_loading />
|
|
||||||
) : (
|
|
||||||
<NodeComments
|
|
||||||
comments={comments}
|
|
||||||
comment_data={comment_data}
|
|
||||||
comment_count={comment_count}
|
|
||||||
user={user}
|
|
||||||
onDelete={nodeLockComment}
|
|
||||||
onEdit={nodeEditComment}
|
|
||||||
onLoadMore={nodeLoadMoreComments}
|
|
||||||
order="ASC"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Group>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const BorisLayout = connect(
|
const BorisLayout = connect(mapStateToProps, mapDispatchToProps)(BorisLayoutUnconnected);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(BorisLayoutUnconnected);
|
|
||||||
|
|
||||||
export { BorisLayout };
|
export { BorisLayout };
|
||||||
|
|
|
@ -8,21 +8,15 @@
|
||||||
.content {
|
.content {
|
||||||
flex: 3;
|
flex: 3;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
padding: $gap;
|
|
||||||
background: $content_bg;
|
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
flex: 0 1 $limited_width;
|
flex: 0 1 $limited_width;
|
||||||
|
padding: 0;
|
||||||
|
background: $node_bg;
|
||||||
|
box-shadow: inset transparentize(mix($wisegreen, white, 60%), 0.6) 0 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.grid {
|
||||||
flex: 1;
|
padding: $gap;
|
||||||
background: $content_bg;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
margin-right: $gap;
|
|
||||||
border-radius: $radius;
|
|
||||||
padding: $gap * 2;
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover {
|
.cover {
|
||||||
|
@ -33,7 +27,7 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: 50% 0% no-repeat url("~/sprites/boris_bg.svg");
|
background: 50% 0% no-repeat url('~/sprites/boris_bg.svg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,32 +35,6 @@
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daygrid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 100%;
|
|
||||||
column-gap: $gap;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.day {
|
|
||||||
font-size: 2em;
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font: $font_14_regular;
|
|
||||||
text-transform: uppercase;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
opacity: 0.5;
|
|
||||||
grid-column: 1/3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line {
|
|
||||||
grid-column: 1/3;
|
|
||||||
height: $gap * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
@ -74,11 +42,6 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex: 0 1 $limited_width;
|
flex: 0 1 $limited_width;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
// margin: auto;
|
|
||||||
|
|
||||||
// @include tablet {
|
|
||||||
// width: 100%;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
|
|
|
@ -20,6 +20,8 @@ import pick from 'ramda/es/pick';
|
||||||
import { NodeRelatedPlaceholder } from '~/components/node/NodeRelated/placeholder';
|
import { NodeRelatedPlaceholder } from '~/components/node/NodeRelated/placeholder';
|
||||||
import { NodeDeletedBadge } from '~/components/node/NodeDeletedBadge';
|
import { NodeDeletedBadge } from '~/components/node/NodeDeletedBadge';
|
||||||
import { NodeCommentForm } from '~/components/node/NodeCommentForm';
|
import { NodeCommentForm } from '~/components/node/NodeCommentForm';
|
||||||
|
import { Sticky } from '~/components/containers/Sticky';
|
||||||
|
import { Footer } from '~/components/main/Footer';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
node: selectNode(state),
|
node: selectNode(state),
|
||||||
|
@ -158,39 +160,40 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<div className={styles.panel}>
|
<div className={styles.panel}>
|
||||||
<Group style={{ flex: 1, minWidth: 0 }}>
|
<Sticky>
|
||||||
{!is_loading && (
|
<Group style={{ flex: 1, minWidth: 0 }}>
|
||||||
<NodeTags is_editable={is_user} tags={node.tags} onChange={onTagsChange} />
|
{!is_loading && (
|
||||||
)}
|
<NodeTags is_editable={is_user} tags={node.tags} onChange={onTagsChange} />
|
||||||
|
)}
|
||||||
|
|
||||||
{is_loading && <NodeRelatedPlaceholder />}
|
{is_loading && <NodeRelatedPlaceholder />}
|
||||||
|
|
||||||
{!is_loading &&
|
{!is_loading &&
|
||||||
related &&
|
related &&
|
||||||
related.albums &&
|
related.albums &&
|
||||||
Object.keys(related.albums)
|
Object.keys(related.albums)
|
||||||
.filter(album => related.albums[album].length > 0)
|
.filter(album => related.albums[album].length > 0)
|
||||||
.map(album => (
|
.map(album => (
|
||||||
<NodeRelated title={album} items={related.albums[album]} key={album} />
|
<NodeRelated title={album} items={related.albums[album]} key={album} />
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{!is_loading && related && related.similar && related.similar.length > 0 && (
|
{!is_loading && related && related.similar && related.similar.length > 0 && (
|
||||||
<NodeRelated title="ПОХОЖИЕ" items={related.similar} />
|
<NodeRelated title="ПОХОЖИЕ" items={related.similar} />
|
||||||
)}
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
|
</Sticky>
|
||||||
</div>
|
</div>
|
||||||
</Group>
|
</Group>
|
||||||
</Padder>
|
</Padder>
|
||||||
</Group>
|
</Group>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Footer />
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const NodeLayout = connect(
|
const NodeLayout = connect(mapStateToProps, mapDispatchToProps)(NodeLayoutUnconnected);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(NodeLayoutUnconnected);
|
|
||||||
|
|
||||||
export { NodeLayout, NodeLayoutUnconnected };
|
export { NodeLayout, NodeLayoutUnconnected };
|
||||||
|
|
10576
yarn-error.log
Normal file
10576
yarn-error.log
Normal file
File diff suppressed because it is too large
Load diff
11
yarn.lock
11
yarn.lock
|
@ -1026,9 +1026,9 @@ acorn-jsx@^5.0.0:
|
||||||
integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==
|
integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==
|
||||||
|
|
||||||
acorn@^6.0.7, acorn@^6.2.1:
|
acorn@^6.0.7, acorn@^6.2.1:
|
||||||
version "6.3.0"
|
version "6.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474"
|
||||||
integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
|
integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
|
||||||
|
|
||||||
add-px-to-style@1.0.0:
|
add-px-to-style@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
|
@ -8510,6 +8510,11 @@ requires-port@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||||
|
|
||||||
|
resize-sensor@^0.0.6:
|
||||||
|
version "0.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/resize-sensor/-/resize-sensor-0.0.6.tgz#75147dcb273de6832760e461d2e28de6dcf88c45"
|
||||||
|
integrity sha512-e+3wwdki9elemYP6AnyG2BK9/Gd7ak46wZN+Z62WwmWfhn2La1XV2rPRRIcar+PhRhfiQDXi29TapGMTIbI3Pg==
|
||||||
|
|
||||||
resolve-cwd@^2.0.0:
|
resolve-cwd@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue