diff --git a/src/components/dialogs/Tabs/index.tsx b/src/components/dialogs/Tabs/index.tsx index 359b8bf9..ad2772c4 100644 --- a/src/components/dialogs/Tabs/index.tsx +++ b/src/components/dialogs/Tabs/index.tsx @@ -13,7 +13,7 @@ const TabContext = createContext({ setActiveTab: (activeTab: number) => {}, }); -const List: VFC = ({ items }) => { +const HorizontalList: VFC = ({ items }) => { const { activeTab, setActiveTab } = useContext(TabContext); return ( @@ -54,7 +54,7 @@ const Tabs = function({ children }) { return {children}; }; -Tabs.List = List; +Tabs.Horizontal = HorizontalList; Tabs.Content = Content; export { Tabs }; diff --git a/src/components/profile/ProfileSidebarSettings/index.tsx b/src/components/profile/ProfileSidebarSettings/index.tsx index ebe8c1e3..046771be 100644 --- a/src/components/profile/ProfileSidebarSettings/index.tsx +++ b/src/components/profile/ProfileSidebarSettings/index.tsx @@ -3,23 +3,34 @@ import React, { FC } from 'react'; import { Filler } from '~/components/containers/Filler'; import { Button } from '~/components/input/Button'; import { ProfileSettings } from '~/components/profile/ProfileSettings'; +import { useStackContext } from '~/components/sidebar/SidebarStack'; +import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard'; import styles from './styles.module.scss'; interface IProps {} -const ProfileSidebarSettings: FC = () => ( -
-
- -
+const ProfileSidebarSettings: FC = () => { + const { closeAllTabs } = useStackContext(); -
- - - -
-
-); + return ( + +
+
+ +
+ +
+ + + + +
+
+
+ ); +}; export { ProfileSidebarSettings }; diff --git a/src/components/profile/ProfileSidebarSettings/styles.module.scss b/src/components/profile/ProfileSidebarSettings/styles.module.scss index 7aeaaded..4bf770da 100644 --- a/src/components/profile/ProfileSidebarSettings/styles.module.scss +++ b/src/components/profile/ProfileSidebarSettings/styles.module.scss @@ -6,6 +6,7 @@ justify-content: center; flex-direction: column; z-index: 4; + height: 100%; } .scroller { @@ -15,6 +16,8 @@ } .buttons { + @include outer_shadow; + width: 100%; padding: $gap; box-sizing: border-box; diff --git a/src/components/sidebar/SidebarStack/index.tsx b/src/components/sidebar/SidebarStack/index.tsx index b1026601..76e2a1bf 100644 --- a/src/components/sidebar/SidebarStack/index.tsx +++ b/src/components/sidebar/SidebarStack/index.tsx @@ -1,10 +1,36 @@ -import React, { FC, useMemo } from 'react'; +import React, { + createContext, + FC, + PropsWithChildren, + useCallback, + useContext, + useMemo, + useState, +} from 'react'; + +import { isNil } from '~/utils/ramda'; import styles from './styles.module.scss'; -interface SidebarStackProps {} +interface SidebarStackProps extends PropsWithChildren<{}> { + initialTab?: number; +} + +interface SidebarStackContextValue { + activeTab?: number; + setActiveTab: (val: number) => void; + closeAllTabs: () => void; +} + +const SidebarStackContext = createContext({ + activeTab: undefined, + setActiveTab: () => {}, + closeAllTabs: () => {}, +}); + +const SidebarCards: FC = ({ children }) => { + const { activeTab } = useStackContext(); -const SidebarStack: FC = ({ children }) => { const nonEmptyChildren = useMemo(() => { if (!children) { return []; @@ -13,15 +39,26 @@ const SidebarStack: FC = ({ children }) => { return Array.isArray(children) ? children.filter(it => it) : [children]; }, [children]); + if (isNil(activeTab) || !nonEmptyChildren[activeTab]) { + return null; + } + + return
{nonEmptyChildren[activeTab]}
; +}; + +const SidebarStack = function({ children, initialTab }: SidebarStackProps) { + const [activeTab, setActiveTab] = useState(initialTab); + const closeAllTabs = useCallback(() => setActiveTab(undefined), []); + return ( -
- {nonEmptyChildren.map((child, i) => ( -
- {child} -
- ))} -
+ +
{children}
+
); }; -export { SidebarStack }; +SidebarStack.Cards = SidebarCards; + +const useStackContext = () => useContext(SidebarStackContext); + +export { SidebarStack, useStackContext }; diff --git a/src/components/sidebar/SidebarStack/styles.module.scss b/src/components/sidebar/SidebarStack/styles.module.scss index 93df686a..8fa51734 100644 --- a/src/components/sidebar/SidebarStack/styles.module.scss +++ b/src/components/sidebar/SidebarStack/styles.module.scss @@ -6,6 +6,12 @@ flex-direction: row-reverse; width: auto; border-radius: $radius 0 0 $radius; + + @include sidebar_stack_limit { + & > *:not(:last-child) { + display: none; + } + } } .card { diff --git a/src/components/sidebar/SidebarStackCard/index.tsx b/src/components/sidebar/SidebarStackCard/index.tsx index a5417231..0eb417e8 100644 --- a/src/components/sidebar/SidebarStackCard/index.tsx +++ b/src/components/sidebar/SidebarStackCard/index.tsx @@ -9,19 +9,28 @@ interface SidebarStackCardProps { width?: number; headerFeature?: 'back' | 'close'; title?: string; + onBackPress?: () => void; } -const SidebarStackCard: FC = ({ children, title, width, headerFeature }) => { +const SidebarStackCard: FC = ({ + children, + title, + width, + headerFeature, + onBackPress, +}) => { const style = useMemo(() => ({ maxWidth: width, flexBasis: width }), [width]); + const backIcon = headerFeature === 'close' ? 'close' : 'right'; return (
- {(headerFeature || title) && ( + {!!(headerFeature || title) && (
- {!!title &&
{title}
}
+ {!!title &&
{title}
}
- {headerFeature === 'back' &&
)} diff --git a/src/components/sidebar/SidebarStackCard/styles.module.scss b/src/components/sidebar/SidebarStackCard/styles.module.scss index e111093d..b374e5fc 100644 --- a/src/components/sidebar/SidebarStackCard/styles.module.scss +++ b/src/components/sidebar/SidebarStackCard/styles.module.scss @@ -17,10 +17,12 @@ flex-direction: row; align-items: center; padding: $gap $gap $gap $gap * 2; + height: 48px; } .content { flex: 1; display: flex; flex-direction: column; + overflow: hidden; } diff --git a/src/containers/profile/ProfileSidebarMenu/index.tsx b/src/containers/profile/ProfileSidebarMenu/index.tsx index 09051d6f..9c6cc2dc 100644 --- a/src/containers/profile/ProfileSidebarMenu/index.tsx +++ b/src/containers/profile/ProfileSidebarMenu/index.tsx @@ -8,6 +8,7 @@ import { Filler } from '~/components/containers/Filler'; import { Grid } from '~/components/containers/Grid'; import { Group } from '~/components/containers/Group'; import { Button } from '~/components/input/Button'; +import { useStackContext } from '~/components/sidebar/SidebarStack'; import { ProfileSidebarHead } from '~/containers/profile/ProfileSidebarHead'; import markdown from '~/styles/common/markdown.module.scss'; @@ -17,54 +18,58 @@ interface ProfileSidebarMenuProps { onClose: () => void; } -const ProfileSidebarMenu: VFC = ({ onClose }) => ( -
-
- +const ProfileSidebarMenu: VFC = ({ onClose }) => { + const { setActiveTab } = useStackContext(); + + return ( +
+
+ +
+ + + +
    +
  • setActiveTab(0)}>Настройки
  • +
  • setActiveTab(1)}>Заметки
  • +
  • setActiveTab(2)}>Удалённые посты
  • +
+ + + +

1 год 2 месяца

+ в убежище +
+ + + +

24 поста

+ Создано +
+
+
+ + + + +

16545 лайка

+ получено +
+
+ + +

123123 комментария

+ под постами +
+
+
+
+ +
- - - -
    -
  • Настройки
  • -
  • Заметки
  • -
  • Удалённые посты
  • -
- - - -

1 год 2 месяца

- в убежище -
- - - -

24 поста

- Создано -
-
-
- - - - -

16545 лайка

- получено -
-
- - -

123123 комментария

- под постами -
-
-
-
- - -
-); + ); +}; export { ProfileSidebarMenu }; diff --git a/src/containers/profile/ProfileSidebarMenu/styles.module.scss b/src/containers/profile/ProfileSidebarMenu/styles.module.scss index 28d4ba6f..2d0d3a50 100644 --- a/src/containers/profile/ProfileSidebarMenu/styles.module.scss +++ b/src/containers/profile/ProfileSidebarMenu/styles.module.scss @@ -3,6 +3,9 @@ .wrap { padding: $gap; box-sizing: border-box; + display: flex; + flex-direction: column; + height: 100%; } .text { diff --git a/src/containers/profile/ProfileTabs/index.tsx b/src/containers/profile/ProfileTabs/index.tsx index 5fd3f47e..e76a8ff7 100644 --- a/src/containers/profile/ProfileTabs/index.tsx +++ b/src/containers/profile/ProfileTabs/index.tsx @@ -13,7 +13,7 @@ const ProfileTabs: FC = ({ is_own }) => { return (
- +
); }; diff --git a/src/containers/sidebars/ProfileSidebar/index.tsx b/src/containers/sidebars/ProfileSidebar/index.tsx index 3ba0ebdd..aa43712f 100644 --- a/src/containers/sidebars/ProfileSidebar/index.tsx +++ b/src/containers/sidebars/ProfileSidebar/index.tsx @@ -1,5 +1,6 @@ import React, { VFC } from 'react'; +import { Tabs } from '~/components/dialogs/Tabs'; import { ProfileSidebarSettings } from '~/components/profile/ProfileSidebarSettings'; import { SidebarStack } from '~/components/sidebar/SidebarStack'; import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard'; @@ -13,13 +14,13 @@ const ProfileSidebar: VFC = ({ onRequestClose }) => { return ( - + - + - + ); diff --git a/src/containers/sidebars/SidebarWrapper/index.tsx b/src/containers/sidebars/SidebarWrapper/index.tsx index d2b0aedf..3e398e08 100644 --- a/src/containers/sidebars/SidebarWrapper/index.tsx +++ b/src/containers/sidebars/SidebarWrapper/index.tsx @@ -8,9 +8,10 @@ import styles from './styles.module.scss'; interface IProps { onClose?: () => void; + closeOnBackdropClick?: boolean; } -const SidebarWrapper: FC = ({ children, onClose }) => { +const SidebarWrapper: FC = ({ children, onClose, closeOnBackdropClick = true }) => { const ref = useRef(null); useCloseOnEscape(onClose); @@ -24,6 +25,7 @@ const SidebarWrapper: FC = ({ children, onClose }) => { return (
+ {closeOnBackdropClick &&
} {children}
); diff --git a/src/containers/sidebars/SidebarWrapper/styles.module.scss b/src/containers/sidebars/SidebarWrapper/styles.module.scss index ef7d2bb1..403da8e8 100644 --- a/src/containers/sidebars/SidebarWrapper/styles.module.scss +++ b/src/containers/sidebars/SidebarWrapper/styles.module.scss @@ -23,3 +23,13 @@ z-index: 4; } } + +.backdrop { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: -1; + cursor: pointer; +} diff --git a/src/layouts/BorisLayout/index.tsx b/src/layouts/BorisLayout/index.tsx index 76442bc5..00ad6750 100644 --- a/src/layouts/BorisLayout/index.tsx +++ b/src/layouts/BorisLayout/index.tsx @@ -1,12 +1,17 @@ import React, { FC } from 'react'; import { BorisSidebar } from '~/components/boris/BorisSidebar'; +import { Superpower } from '~/components/boris/Superpower'; import { Card } from '~/components/containers/Card'; import { Group } from '~/components/containers/Group'; +import { Padder } from '~/components/containers/Padder'; import { Sticky } from '~/components/containers/Sticky'; +import { Button } from '~/components/input/Button'; +import { Dialog } from '~/constants/modal'; import { BorisComments } from '~/containers/boris/BorisComments'; import { Container } from '~/containers/main/Container'; import { SidebarRouter } from '~/containers/main/SidebarRouter'; +import { useShowModal } from '~/hooks/modal/useShowModal'; import { BorisUsageStats } from '~/types/boris'; import { useAuthProvider } from '~/utils/providers/AuthProvider'; @@ -22,6 +27,7 @@ type IProps = { const BorisLayout: FC = ({ title, setIsBetaTester, isTester, stats, isLoadingStats }) => { const { isUser } = useAuthProvider(); + const openProfileSidebar = useShowModal(Dialog.ProfileSidebar); return ( @@ -38,6 +44,14 @@ const BorisLayout: FC = ({ title, setIsBetaTester, isTester, stats, isLo
+ + +

Тестовые фичи

+ +
+ +
+
diff --git a/src/styles/_global.scss b/src/styles/_global.scss index d14f2b19..6b64010a 100644 --- a/src/styles/_global.scss +++ b/src/styles/_global.scss @@ -129,11 +129,16 @@ button { outline: none; } -h5, h4, h3, h2, h1 { +h3, h2, h1 { color: white; font-weight: 800; } +h6, h5, h4 { + color: white; + font-weight: 600; +} + h1 { font-size: 2em; } @@ -154,6 +159,10 @@ h5 { font-size: 1.2em; } +h6 { + font-size: 1em; +} + p { margin-bottom: $gap; diff --git a/src/styles/_mixins.scss b/src/styles/_mixins.scss index b84f8da3..c23fc8fc 100644 --- a/src/styles/_mixins.scss +++ b/src/styles/_mixins.scss @@ -85,6 +85,12 @@ } } +@mixin sidebar_stack_limit { + @media (max-width: 1000px) { + @content; + } +} + @mixin desktop { @media (max-width: $content_width) { @content;