mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-26 05:16: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
|
@ -1,151 +0,0 @@
|
|||
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, Link } 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';
|
||||
|
||||
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>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export { BorisLayout };
|
|
@ -1,159 +0,0 @@
|
|||
@import "src/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;
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
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 };
|
|
@ -1,44 +0,0 @@
|
|||
@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