mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
#23 fixed submit button appearance for lab
This commit is contained in:
parent
998a2e305a
commit
ede5dfe17f
15 changed files with 82 additions and 44 deletions
154
src/layouts/BorisLayout/index.tsx
Normal file
154
src/layouts/BorisLayout/index.tsx
Normal file
|
@ -0,0 +1,154 @@
|
|||
import React, { FC, useCallback, useEffect } from 'react';
|
||||
import { selectNode, selectNodeComments } from '~/redux/node/selectors';
|
||||
import { selectAuthIsTester, selectUser } from '~/redux/auth/selectors';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import styles from './styles.module.scss';
|
||||
import { Group } from '~/components/containers/Group';
|
||||
import boris from '~/sprites/boris_robot.svg';
|
||||
import { useRandomPhrase } from '~/constants/phrases';
|
||||
import isBefore from 'date-fns/isBefore';
|
||||
import { BorisStats } from '~/components/boris/BorisStats';
|
||||
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
|
||||
import { selectBorisStats } from '~/redux/boris/selectors';
|
||||
import { authSetState, authSetUser } from '~/redux/auth/actions';
|
||||
import { nodeLoadNode } from '~/redux/node/actions';
|
||||
import { borisLoadStats } from '~/redux/boris/actions';
|
||||
import { Container } from '~/containers/main/Container';
|
||||
import StickyBox from 'react-sticky-box/dist/esnext';
|
||||
import { BorisComments } from '~/components/boris/BorisComments';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import { BorisUIDemo } from '~/components/boris/BorisUIDemo';
|
||||
import { BorisSuperpowers } from '~/components/boris/BorisSuperpowers';
|
||||
import { Superpower } from '~/components/boris/Superpower';
|
||||
import { Tabs } from '~/components/dialogs/Tabs';
|
||||
import { Tab } from '~/components/dialogs/Tab';
|
||||
import { useHistory, useLocation } from 'react-router';
|
||||
import { Card } from '~/components/containers/Card';
|
||||
import { SidebarRouter } from '~/containers/main/SidebarRouter';
|
||||
|
||||
type IProps = {};
|
||||
|
||||
const BorisLayout: FC<IProps> = () => {
|
||||
const title = useRandomPhrase('BORIS_TITLE');
|
||||
const dispatch = useDispatch();
|
||||
const node = useShallowSelect(selectNode);
|
||||
const user = useShallowSelect(selectUser);
|
||||
const stats = useShallowSelect(selectBorisStats);
|
||||
const comments = useShallowSelect(selectNodeComments);
|
||||
const is_tester = useShallowSelect(selectAuthIsTester);
|
||||
|
||||
useEffect(() => {
|
||||
const last_comment = comments[0];
|
||||
|
||||
if (!last_comment) return;
|
||||
|
||||
if (
|
||||
user.last_seen_boris &&
|
||||
last_comment.created_at &&
|
||||
!isBefore(new Date(user.last_seen_boris), new Date(last_comment.created_at))
|
||||
)
|
||||
return;
|
||||
|
||||
dispatch(authSetUser({ last_seen_boris: last_comment.created_at }));
|
||||
}, [user.last_seen_boris, dispatch, comments]);
|
||||
|
||||
useEffect(() => {
|
||||
if (node.is_loading) return;
|
||||
dispatch(nodeLoadNode(696, 'DESC'));
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(borisLoadStats());
|
||||
}, [dispatch]);
|
||||
|
||||
const setBetaTester = useCallback(
|
||||
(is_tester: boolean) => {
|
||||
dispatch(authSetState({ is_tester }));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div className={styles.wrap}>
|
||||
<div className={styles.cover} />
|
||||
|
||||
<div className={styles.image}>
|
||||
<div className={styles.caption}>
|
||||
<div className={styles.caption_text}>{title}</div>
|
||||
</div>
|
||||
|
||||
<img src={boris} alt="Борис" />
|
||||
</div>
|
||||
|
||||
<div className={styles.container}>
|
||||
<Card className={styles.content}>
|
||||
<Superpower>
|
||||
<Tabs>
|
||||
<Tab
|
||||
active={location.pathname === URLS.BORIS}
|
||||
onClick={() => history.push(URLS.BORIS)}
|
||||
>
|
||||
Комментарии
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
active={location.pathname === `${URLS.BORIS}/ui`}
|
||||
onClick={() => history.push(`${URLS.BORIS}/ui`)}
|
||||
>
|
||||
UI Demo
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Superpower>
|
||||
|
||||
{
|
||||
<Switch>
|
||||
<Route path={`${URLS.BORIS}/ui`} component={BorisUIDemo} />
|
||||
|
||||
<BorisComments
|
||||
isLoadingComments={node.is_loading_comments}
|
||||
commentCount={node.comment_count}
|
||||
node={node.current}
|
||||
comments={node.comments}
|
||||
/>
|
||||
</Switch>
|
||||
}
|
||||
</Card>
|
||||
|
||||
<Group className={styles.stats}>
|
||||
<StickyBox className={styles.sticky} offsetTop={72} offsetBottom={10}>
|
||||
<Group className={styles.stats__container}>
|
||||
<div className={styles.stats__about}>
|
||||
<h4>Господи-боженьки, где это я?</h4>
|
||||
|
||||
<p>
|
||||
Всё впорядке, это — главный штаб Суицидальных Роботов, строителей Убежища.
|
||||
</p>
|
||||
<p>Здесь мы сидим и слушаем всё, что вас беспокоит.</p>
|
||||
<p>Все виновные будут наказаны. Невиновные, впрочем, тоже. </p>
|
||||
<p className="grey">// Такова жизнь.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{user.is_user && <BorisSuperpowers active={is_tester} onChange={setBetaTester} />}
|
||||
</div>
|
||||
|
||||
<div className={styles.stats__wrap}>
|
||||
<BorisStats stats={stats} />
|
||||
</div>
|
||||
</Group>
|
||||
</StickyBox>
|
||||
</Group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SidebarRouter prefix="/" />
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export { BorisLayout };
|
159
src/layouts/BorisLayout/styles.module.scss
Normal file
159
src/layouts/BorisLayout/styles.module.scss
Normal file
|
@ -0,0 +1,159 @@
|
|||
@import "~/styles/variables";
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
.grid {
|
||||
padding: $gap;
|
||||
}
|
||||
|
||||
.cover {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: 50% 0 no-repeat url('../../sprites/boris_bg.svg');
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.header {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
|
||||
@include tablet {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-bottom: 33.333%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@include tablet {
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
padding-bottom: 0;
|
||||
|
||||
img {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.caption {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-end;
|
||||
font: $font_48_bold;
|
||||
font-size: 72px;
|
||||
line-height: 0.95em;
|
||||
flex-direction: column;
|
||||
padding-bottom: $gap * 2;
|
||||
padding: 0 0 $gap * 2;
|
||||
transform: translate(-50%, 0);
|
||||
box-sizing: border-box;
|
||||
|
||||
@include tablet {
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
display: none;
|
||||
|
||||
padding: $gap;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.caption_text {
|
||||
max-width: 400px;
|
||||
text-transform: uppercase;
|
||||
|
||||
@include tablet {
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.stats {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
align-self: stretch;
|
||||
flex-direction: column;
|
||||
padding-top: 10px;
|
||||
|
||||
h4 {
|
||||
font: $font_20_semibold;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: $gap * 2;
|
||||
}
|
||||
|
||||
&__container {
|
||||
background: darken($content_bg, 4%);
|
||||
border-radius: 0 $radius $radius 0;
|
||||
box-shadow: inset transparentize(mix($wisegreen, white, 60%), 0.6) 0 1px;
|
||||
padding: $gap;
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font: $font_12_semibold;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.3;
|
||||
margin-top: 16px !important;
|
||||
}
|
||||
|
||||
&__about {
|
||||
line-height: 1.4em;
|
||||
|
||||
p {
|
||||
margin-bottom: $gap;
|
||||
}
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
@include tablet {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 3;
|
||||
}
|
97
src/layouts/FlowLayout/index.tsx
Normal file
97
src/layouts/FlowLayout/index.tsx
Normal file
|
@ -0,0 +1,97 @@
|
|||
import React, { FC, useCallback, useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { FlowGrid } from '~/components/flow/FlowGrid';
|
||||
import { selectFlow } from '~/redux/flow/selectors';
|
||||
import * as NODE_ACTIONS from '~/redux/node/actions';
|
||||
import * as FLOW_ACTIONS from '~/redux/flow/actions';
|
||||
import { pick } from 'ramda';
|
||||
import { selectUser } from '~/redux/auth/selectors';
|
||||
import { FlowHero } from '~/components/flow/FlowHero';
|
||||
import styles from './styles.module.scss';
|
||||
import { IState } from '~/redux/store';
|
||||
import { FlowStamp } from '~/components/flow/FlowStamp';
|
||||
import { Container } from '~/containers/main/Container';
|
||||
import { SidebarRouter } from '~/containers/main/SidebarRouter';
|
||||
|
||||
const mapStateToProps = (state: IState) => ({
|
||||
flow: pick(['nodes', 'heroes', 'recent', 'updated', 'is_loading', 'search'], selectFlow(state)),
|
||||
user: pick(['role', 'id'], selectUser(state)),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
nodeGotoNode: NODE_ACTIONS.nodeGotoNode,
|
||||
flowSetCellView: FLOW_ACTIONS.flowSetCellView,
|
||||
flowGetMore: FLOW_ACTIONS.flowGetMore,
|
||||
flowChangeSearch: FLOW_ACTIONS.flowChangeSearch,
|
||||
flowLoadMoreSearch: FLOW_ACTIONS.flowLoadMoreSearch,
|
||||
};
|
||||
|
||||
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
||||
|
||||
const FlowLayoutUnconnected: FC<IProps> = ({
|
||||
flow: { nodes, heroes, recent, updated, is_loading, search },
|
||||
user,
|
||||
nodeGotoNode,
|
||||
flowSetCellView,
|
||||
flowGetMore,
|
||||
flowChangeSearch,
|
||||
flowLoadMoreSearch,
|
||||
}) => {
|
||||
const onLoadMore = useCallback(() => {
|
||||
(window as any).flowScrollPos = window.scrollY;
|
||||
|
||||
const pos = window.scrollY + window.innerHeight - document.body.scrollHeight;
|
||||
|
||||
if (is_loading || pos < -600) return;
|
||||
|
||||
flowGetMore();
|
||||
}, [flowGetMore, is_loading]);
|
||||
|
||||
const onLoadMoreSearch = useCallback(() => {
|
||||
if (search.is_loading_more) return;
|
||||
flowLoadMoreSearch();
|
||||
}, [search.is_loading_more, flowLoadMoreSearch]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('scroll', onLoadMore);
|
||||
|
||||
return () => window.removeEventListener('scroll', onLoadMore);
|
||||
}, [onLoadMore]);
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, (window as any).flowScrollPos || 0);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div className={styles.grid}>
|
||||
<div className={styles.hero}>
|
||||
<FlowHero heroes={heroes} />
|
||||
</div>
|
||||
|
||||
<div className={styles.stamp}>
|
||||
<FlowStamp
|
||||
recent={recent}
|
||||
updated={updated}
|
||||
search={search}
|
||||
flowChangeSearch={flowChangeSearch}
|
||||
onLoadMore={onLoadMoreSearch}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FlowGrid
|
||||
nodes={nodes}
|
||||
user={user}
|
||||
onSelect={nodeGotoNode}
|
||||
onChangeCellView={flowSetCellView}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<SidebarRouter prefix="/" />
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
const FlowLayout = connect(mapStateToProps, mapDispatchToProps)(FlowLayoutUnconnected);
|
||||
|
||||
export { FlowLayout, FlowLayoutUnconnected };
|
86
src/layouts/FlowLayout/styles.module.scss
Normal file
86
src/layouts/FlowLayout/styles.module.scss
Normal file
|
@ -0,0 +1,86 @@
|
|||
@import "src/styles/variables";
|
||||
|
||||
.wrap {
|
||||
max-width: 2000px;
|
||||
padding: 0 40px 40px 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
$cols: $content_width / $cell;
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-template-rows: 50vh $cell;
|
||||
grid-auto-rows: $cell;
|
||||
|
||||
grid-auto-flow: row dense;
|
||||
grid-column-gap: $gap;
|
||||
grid-row-gap: $gap;
|
||||
|
||||
@include tablet {
|
||||
padding: 0 $gap;
|
||||
}
|
||||
|
||||
@media (max-width: $cell * 6) {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-template-rows: 50vh 20vw;
|
||||
grid-auto-rows: 20vw;
|
||||
}
|
||||
|
||||
@media (max-width: $cell * 5) {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-template-rows: 40vh 25vw;
|
||||
grid-auto-rows: 25vw;
|
||||
}
|
||||
|
||||
@media (max-width: $cell * 4) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: 40vh 33vw;
|
||||
grid-auto-rows: 33vw;
|
||||
}
|
||||
|
||||
@media (max-width: $cell * 3) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: 40vh 50vw;
|
||||
grid-auto-rows: 50vw;
|
||||
grid-column-gap: $gap / 2;
|
||||
grid-row-gap: $gap / 2;
|
||||
padding: 0 $gap / 2;
|
||||
}
|
||||
|
||||
@media (max-width: $cell * 2) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: 40vh 50vw;
|
||||
grid-auto-rows: 50vw;
|
||||
}
|
||||
}
|
||||
|
||||
.pad_last {
|
||||
grid-column-end: $cols + 1;
|
||||
}
|
||||
|
||||
.hero {
|
||||
grid-row-start: 1;
|
||||
grid-row-end: span 1;
|
||||
grid-column-start: 1;
|
||||
grid-column-end: -1;
|
||||
background: darken($content_bg, 2%);
|
||||
border-radius: $radius;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font: $font_24_semibold;
|
||||
}
|
||||
|
||||
.stamp {
|
||||
grid-row-end: span 2;
|
||||
grid-column: -2 / -1;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: stretch;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
54
src/layouts/LabLayout/index.tsx
Normal file
54
src/layouts/LabLayout/index.tsx
Normal file
|
@ -0,0 +1,54 @@
|
|||
import React, { FC, useEffect } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { Card } from '~/components/containers/Card';
|
||||
import { Sticky } from '~/components/containers/Sticky';
|
||||
import { Container } from '~/containers/main/Container';
|
||||
import { LabGrid } from '~/containers/lab/LabGrid';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { labGetList, labGetStats } from '~/redux/lab/actions';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { Grid } from '~/components/containers/Grid';
|
||||
import { Group } from '~/components/containers/Group';
|
||||
import { LabHero } from '~/components/lab/LabHero';
|
||||
import { LabBanner } from '~/components/lab/LabBanner';
|
||||
import { LabHead } from '~/components/lab/LabHead';
|
||||
import { Filler } from '~/components/containers/Filler';
|
||||
import { LabStats } from '~/containers/lab/LabStats';
|
||||
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
|
||||
import { selectLabList, selectLabListNodes, selectLabStatsLoading } from '~/redux/lab/selectors';
|
||||
import { SidebarRouter } from '~/containers/main/SidebarRouter';
|
||||
|
||||
interface IProps {}
|
||||
|
||||
const LabLayout: FC<IProps> = () => {
|
||||
const { is_loading } = useShallowSelect(selectLabList);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(labGetList());
|
||||
dispatch(labGetStats());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Container>
|
||||
<div className={styles.wrap}>
|
||||
<Group className={styles.content}>
|
||||
<LabHead isLoading={is_loading} />
|
||||
<LabGrid />
|
||||
</Group>
|
||||
|
||||
<div className={styles.panel}>
|
||||
<Sticky>
|
||||
<LabStats />
|
||||
</Sticky>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
<SidebarRouter prefix="/lab" isLab />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { LabLayout };
|
26
src/layouts/LabLayout/styles.module.scss
Normal file
26
src/layouts/LabLayout/styles.module.scss
Normal file
|
@ -0,0 +1,26 @@
|
|||
@import "~/styles/variables.scss";
|
||||
|
||||
.wrap {
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 1fr;
|
||||
column-gap: $gap;
|
||||
|
||||
@include tablet {
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-flow: row;
|
||||
padding: 0 $gap / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
margin-top: -7px;
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
& > * {
|
||||
margin: 0 $gap $gap 0;
|
||||
}
|
||||
}
|
72
src/layouts/NodeLayout/index.tsx
Normal file
72
src/layouts/NodeLayout/index.tsx
Normal file
|
@ -0,0 +1,72 @@
|
|||
import React, { FC, memo } from 'react';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
import { selectNode } from '~/redux/node/selectors';
|
||||
import { Card } from '~/components/containers/Card';
|
||||
|
||||
import { NodePanel } from '~/components/node/NodePanel';
|
||||
import { Footer } from '~/components/main/Footer';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
import { SidebarRouter } from '~/containers/main/SidebarRouter';
|
||||
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
|
||||
import { Container } from '~/containers/main/Container';
|
||||
import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks';
|
||||
import { NodeBottomBlock } from '~/components/node/NodeBottomBlock';
|
||||
import { useNodeCoverImage } from '~/utils/hooks/node/useNodeCoverImage';
|
||||
import { useScrollToTop } from '~/utils/hooks/useScrollToTop';
|
||||
import { useLoadNode } from '~/utils/hooks/node/useLoadNode';
|
||||
|
||||
type IProps = RouteComponentProps<{ id: string }> & {};
|
||||
|
||||
const NodeLayout: FC<IProps> = memo(
|
||||
({
|
||||
match: {
|
||||
params: { id },
|
||||
},
|
||||
}) => {
|
||||
const {
|
||||
is_loading,
|
||||
current,
|
||||
comments,
|
||||
comment_count,
|
||||
is_loading_comments,
|
||||
related,
|
||||
} = useShallowSelect(selectNode);
|
||||
|
||||
useNodeCoverImage(current);
|
||||
useScrollToTop([id]);
|
||||
useLoadNode(id, is_loading);
|
||||
|
||||
const { head, block } = useNodeBlocks(current, is_loading);
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
{head}
|
||||
|
||||
<Container>
|
||||
<Card className={styles.node} seamless>
|
||||
{block}
|
||||
|
||||
<NodePanel node={current} isLoading={is_loading} />
|
||||
|
||||
<NodeBottomBlock
|
||||
node={current}
|
||||
isLoadingComments={is_loading_comments}
|
||||
comments={comments}
|
||||
isLoading={is_loading}
|
||||
commentsCount={comment_count}
|
||||
commentsOrder="DESC"
|
||||
related={related}
|
||||
/>
|
||||
|
||||
<Footer />
|
||||
</Card>
|
||||
</Container>
|
||||
|
||||
<SidebarRouter prefix="/post:id" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export { NodeLayout };
|
44
src/layouts/NodeLayout/styles.module.scss
Normal file
44
src/layouts/NodeLayout/styles.module.scss
Normal file
|
@ -0,0 +1,44 @@
|
|||
@import "src/styles/variables";
|
||||
|
||||
.content {
|
||||
align-items: stretch !important;
|
||||
|
||||
@include vertical_at_tablet;
|
||||
}
|
||||
|
||||
.comments {
|
||||
flex: 3 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
flex: 2 1;
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
flex: 1 3;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding-left: $gap / 2;
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
padding-left: 0;
|
||||
padding-top: $comment_height / 2;
|
||||
flex: 1 2;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
background: $node_buttons_bg;
|
||||
flex: 1;
|
||||
border-radius: $panel_radius;
|
||||
box-shadow: $comment_shadow;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue