mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-26 05:16:41 +07:00
removed redux completely
This commit is contained in:
parent
26e6d8d41b
commit
a4bb07e9cf
323 changed files with 2464 additions and 3348 deletions
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from "react";
|
||||
import styles from "./styles.module.scss";
|
||||
import { PlayerView } from "~/containers/player/PlayerView";
|
||||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { PlayerView } from '~/containers/player/PlayerView';
|
||||
|
||||
type IProps = {};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from "react";
|
||||
import styles from "./styles.module.scss";
|
||||
import classNames from "classnames";
|
||||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
|
|
106
src/containers/main/Header/index.tsx
Normal file
106
src/containers/main/Header/index.tsx
Normal file
|
@ -0,0 +1,106 @@
|
|||
import React, { FC, useCallback, useMemo } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Logo } from '~/components/main/Logo';
|
||||
|
||||
import { Filler } from '~/components/containers/Filler';
|
||||
import { UserButton } from '~/components/main/UserButton';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './styles.module.scss';
|
||||
import isBefore from 'date-fns/isBefore';
|
||||
import { Authorized } from '~/components/containers/Authorized';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { observer } from 'mobx-react';
|
||||
import { Dialog } from '~/constants/modal';
|
||||
import { useGetLabStats } from '~/hooks/lab/useGetLabStats';
|
||||
import { useAuth } from '~/hooks/auth/useAuth';
|
||||
import { useModal } from '~/hooks/modal/useModal';
|
||||
import { useScrollTop } from '~/hooks/dom/useScrollTop';
|
||||
import { useFlow } from '~/hooks/flow/useFlow';
|
||||
import { useUpdates } from '~/hooks/updates/useUpdates';
|
||||
|
||||
type HeaderProps = {};
|
||||
|
||||
const Header: FC<HeaderProps> = observer(() => {
|
||||
const labStats = useGetLabStats();
|
||||
|
||||
const { logout } = useAuth();
|
||||
const { showModal } = useModal();
|
||||
const { isUser, user } = useAuth();
|
||||
const { updates: flowUpdates } = useFlow();
|
||||
const { borisCommentedAt } = useUpdates();
|
||||
|
||||
const openProfile = useCallback(() => {
|
||||
showModal(Dialog.Profile, { username: user.username });
|
||||
}, [user.username, showModal]);
|
||||
|
||||
const onLogin = useCallback(() => showModal(Dialog.Login, {}), [showModal]);
|
||||
|
||||
const top = useScrollTop();
|
||||
|
||||
const hasBorisUpdates = useMemo(
|
||||
() =>
|
||||
isUser &&
|
||||
borisCommentedAt &&
|
||||
(!user.last_seen_boris ||
|
||||
isBefore(new Date(user.last_seen_boris), new Date(borisCommentedAt))),
|
||||
[borisCommentedAt, isUser, user.last_seen_boris]
|
||||
);
|
||||
|
||||
const hasLabUpdates = useMemo(() => labStats.updates.length > 0, [labStats.updates]);
|
||||
const hasFlowUpdates = useMemo(() => flowUpdates.length > 0, [flowUpdates]);
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.wrap, { [styles.is_scrolled]: top > 10 })}>
|
||||
<div className={styles.container}>
|
||||
<div className={classNames(styles.logo_wrapper, { [styles.logged_in]: isUser })}>
|
||||
<Logo />
|
||||
</div>
|
||||
|
||||
<Filler className={styles.filler} />
|
||||
|
||||
<div className={styles.plugs}>
|
||||
<Authorized>
|
||||
<Link
|
||||
className={classNames(styles.item, {
|
||||
[styles.has_dot]: hasFlowUpdates,
|
||||
})}
|
||||
to={URLS.BASE}
|
||||
>
|
||||
ФЛОУ
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
className={classNames(styles.item, styles.lab, {
|
||||
[styles.has_dot]: hasLabUpdates,
|
||||
})}
|
||||
to={URLS.LAB}
|
||||
>
|
||||
ЛАБ
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
className={classNames(styles.item, styles.boris, {
|
||||
[styles.has_dot]: hasBorisUpdates,
|
||||
})}
|
||||
to={URLS.BORIS}
|
||||
>
|
||||
БОРИС
|
||||
</Link>
|
||||
</Authorized>
|
||||
</div>
|
||||
|
||||
{isUser && <UserButton user={user} onLogout={logout} authOpenProfile={openProfile} />}
|
||||
|
||||
{!isUser && (
|
||||
<Button className={styles.user_button} onClick={onLogin} round color="secondary">
|
||||
ВДОХ
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export { Header };
|
152
src/containers/main/Header/styles.module.scss
Normal file
152
src/containers/main/Header/styles.module.scss
Normal file
|
@ -0,0 +1,152 @@
|
|||
@import "../../../styles/variables";
|
||||
|
||||
.wrap {
|
||||
height: $header_height;
|
||||
z-index: 25;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
transition: background-color 0.5s;
|
||||
|
||||
@include desktop {
|
||||
height: 64px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.is_scrolled {
|
||||
@include blur();
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
@include container;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
font-weight: 500;
|
||||
box-sizing: border-box;
|
||||
|
||||
@include tablet {
|
||||
padding: 0 $gap;
|
||||
}
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.plugs {
|
||||
display: flex;
|
||||
user-select: none;
|
||||
text-transform: uppercase;
|
||||
align-items: center;
|
||||
|
||||
@include tablet {
|
||||
flex: 1;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.profile {
|
||||
padding: 5px 10px;
|
||||
box-shadow: white 0 0 0 1px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.user_button {
|
||||
flex: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item {
|
||||
font: $font_16_medium;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: $gap $gap * 2;
|
||||
cursor: pointer;
|
||||
transition: color 0.25s;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
color: $red;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
width: 50%;
|
||||
right: 50%;
|
||||
background: white;
|
||||
transform: translate(50%, 0) scaleX(0);
|
||||
opacity: 0;
|
||||
border-radius: 3px;
|
||||
transition: transform 0.5s, opacity 0.25s;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 4px;
|
||||
background: lighten($red, 10%);
|
||||
right: 12px;
|
||||
top: 6px;
|
||||
transition: opacity 0.5s;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&.has_dot {
|
||||
&::after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.lab::after {
|
||||
background: lighten($blue, 10%);
|
||||
}
|
||||
|
||||
&.boris::after {
|
||||
background: lighten($wisegreen, 10%);
|
||||
}
|
||||
|
||||
@include tablet {
|
||||
padding: 0 $gap * 2 0 0;
|
||||
|
||||
&.notifications {
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-right: $gap;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filler {
|
||||
@include tablet {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.logo_wrapper {
|
||||
|
||||
@include tablet {
|
||||
&.logged_in {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { Header } from '~/components/main/Header';
|
||||
import { Header } from '~/containers/main/Header';
|
||||
|
||||
export const MainLayout = ({ children }) => (
|
||||
<div className={styles.wrapper}>
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import React, { FC } from "react";
|
||||
import { URLS } from "~/constants/urls";
|
||||
import { ErrorNotFound } from "~/containers/pages/ErrorNotFound";
|
||||
import { Redirect, Route, Switch, useLocation } from "react-router";
|
||||
import { useShallowSelect } from "~/hooks/data/useShallowSelect";
|
||||
import { selectAuthUser } from "~/redux/auth/selectors";
|
||||
import { ProfileLayout } from "~/layouts/ProfileLayout";
|
||||
import FlowPage from "~/pages";
|
||||
import BorisPage from "~/pages/boris";
|
||||
import NodePage from "~/pages/node/[id]";
|
||||
import LabPage from "~/pages/lab";
|
||||
import React, { FC } from 'react';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import { ErrorNotFound } from '~/containers/pages/ErrorNotFound';
|
||||
import { Redirect, Route, Switch, useLocation } from 'react-router';
|
||||
import { ProfileLayout } from '~/layouts/ProfileLayout';
|
||||
import FlowPage from '~/pages';
|
||||
import BorisPage from '~/pages/boris';
|
||||
import NodePage from '~/pages/node/[id]';
|
||||
import LabPage from '~/pages/lab';
|
||||
import { useAuth } from '~/hooks/auth/useAuth';
|
||||
|
||||
interface IProps {}
|
||||
|
||||
const MainRouter: FC<IProps> = () => {
|
||||
const { is_user } = useShallowSelect(selectAuthUser);
|
||||
const { isUser } = useAuth();
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
|
@ -23,7 +22,7 @@ const MainRouter: FC<IProps> = () => {
|
|||
<Route path={URLS.ERRORS.NOT_FOUND} component={ErrorNotFound} />
|
||||
<Route path={URLS.PROFILE_PAGE(':username')} component={ProfileLayout} />
|
||||
|
||||
{is_user && <Route path={URLS.LAB} component={LabPage} />}
|
||||
{isUser && <Route path={URLS.LAB} component={LabPage} />}
|
||||
|
||||
<Route path={URLS.BASE} component={FlowPage} />
|
||||
<Redirect to="/" />
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React, { FC } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { Route, Switch } from "react-router";
|
||||
import { TagSidebar } from "~/containers/sidebars/TagSidebar";
|
||||
import { Authorized } from "~/components/containers/Authorized";
|
||||
import { SubmitBar } from "~/components/bars/SubmitBar";
|
||||
import { EditorCreateDialog } from "~/containers/dialogs/EditorCreateDialog";
|
||||
import React, { FC } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { TagSidebar } from '~/containers/sidebars/TagSidebar';
|
||||
import { Authorized } from '~/components/containers/Authorized';
|
||||
import { SubmitBar } from '~/components/bars/SubmitBar';
|
||||
import { EditorCreateDialog } from '~/containers/dialogs/EditorCreateDialog';
|
||||
|
||||
interface IProps {
|
||||
prefix?: string;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue