1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

moved tags to sidebar

This commit is contained in:
Fedor Katurov 2022-08-15 12:32:44 +07:00
parent a8ac233140
commit f6109d8862
13 changed files with 99 additions and 71 deletions

View file

@ -1,12 +1,14 @@
import React, { FC } from 'react'; import React, { FC, useCallback } from 'react';
import { Pressable } from '~/components/common/Pressable'; import { Pressable } from '~/components/common/Pressable';
import { NodeRelated } from '~/components/node/NodeRelated'; import { NodeRelated } from '~/components/node/NodeRelated';
import { NodeRelatedPlaceholder } from '~/components/node/NodeRelated/placeholder'; import { NodeRelatedPlaceholder } from '~/components/node/NodeRelated/placeholder';
import { Dialog } from '~/constants/modal'; import { Dialog } from '~/constants/modal';
import { useShowModal } from '~/hooks/modal/useShowModal'; import { useShowModal } from '~/hooks/modal/useShowModal';
import { INode } from '~/types'; import { useTagSidebar } from '~/hooks/sidebar/useTagSidebar';
import { INode, ITag } from '~/types';
import { INodeRelated } from '~/types/node'; import { INodeRelated } from '~/types/node';
import { useSidebar } from '~/utils/providers/SidebarProvider';
interface IProps { interface IProps {
isLoading: boolean; isLoading: boolean;
@ -15,7 +17,7 @@ interface IProps {
} }
const NodeRelatedBlock: FC<IProps> = ({ isLoading, node, related }) => { const NodeRelatedBlock: FC<IProps> = ({ isLoading, node, related }) => {
const goToTag = useShowModal(Dialog.TagSidebar); const goToTag = useTagSidebar();
if (isLoading) { if (isLoading) {
return <NodeRelatedPlaceholder />; return <NodeRelatedPlaceholder />;
@ -27,10 +29,12 @@ const NodeRelatedBlock: FC<IProps> = ({ isLoading, node, related }) => {
related.albums && related.albums &&
!!node?.id && !!node?.id &&
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 <NodeRelated
title={<Pressable onClick={() => goToTag({ tag: album })}>{album}</Pressable>} title={
<Pressable onClick={() => goToTag(album)}>{album}</Pressable>
}
items={related.albums[album]} items={related.albums[album]}
key={album} key={album}
/> />

View file

@ -1,4 +1,4 @@
import React, { FC, useMemo } from 'react'; import React, { FC, ReactNode, useMemo } from 'react';
import { Filler } from '~/components/containers/Filler'; import { Filler } from '~/components/containers/Filler';
import { Button } from '~/components/input/Button'; import { Button } from '~/components/input/Button';
@ -8,7 +8,7 @@ import styles from './styles.module.scss';
interface SidebarStackCardProps { interface SidebarStackCardProps {
width?: number; width?: number;
headerFeature?: 'back' | 'close'; headerFeature?: 'back' | 'close';
title?: string; title?: ReactNode;
onBackPress?: () => void; onBackPress?: () => void;
} }
@ -26,7 +26,9 @@ const SidebarStackCard: FC<SidebarStackCardProps> = ({
<div style={style} className={styles.card}> <div style={style} className={styles.card}>
{!!(headerFeature || title) && ( {!!(headerFeature || title) && (
<div className={styles.head}> <div className={styles.head}>
<Filler>{!!title && <h6>{title}</h6>}</Filler> <Filler className={styles.title}>
{typeof title === 'string' ? <h6>{title}</h6> : title}
</Filler>
{!!(headerFeature && onBackPress) && ( {!!(headerFeature && onBackPress) && (
<Button color="link" iconRight={backIcon} onClick={onBackPress} /> <Button color="link" iconRight={backIcon} onClick={onBackPress} />

View file

@ -1,4 +1,4 @@
@import "src/styles/variables"; @import 'src/styles/variables';
.card { .card {
width: 100vw; width: 100vw;
@ -28,3 +28,8 @@
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
} }
.title {
display: flex;
align-items: center;
}

View file

@ -7,7 +7,6 @@ import { PhotoSwipe } from '~/containers/dialogs/PhotoSwipe';
import { RestorePasswordDialog } from '~/containers/dialogs/RestorePasswordDialog'; import { RestorePasswordDialog } from '~/containers/dialogs/RestorePasswordDialog';
import { RestoreRequestDialog } from '~/containers/dialogs/RestoreRequestDialog'; import { RestoreRequestDialog } from '~/containers/dialogs/RestoreRequestDialog';
import { TestDialog } from '~/containers/dialogs/TestDialog'; import { TestDialog } from '~/containers/dialogs/TestDialog';
import { TagSidebar } from '~/containers/sidebars/TagSidebar';
export enum Dialog { export enum Dialog {
Login = 'Login', Login = 'Login',
@ -19,7 +18,6 @@ export enum Dialog {
Photoswipe = 'Photoswipe', Photoswipe = 'Photoswipe',
CreateNode = 'CreateNode', CreateNode = 'CreateNode',
EditNode = 'EditNode', EditNode = 'EditNode',
TagSidebar = 'TagNodes',
} }
export const DIALOG_CONTENT = { export const DIALOG_CONTENT = {
@ -32,5 +30,4 @@ export const DIALOG_CONTENT = {
[Dialog.Photoswipe]: PhotoSwipe, [Dialog.Photoswipe]: PhotoSwipe,
[Dialog.CreateNode]: EditorCreateDialog, [Dialog.CreateNode]: EditorCreateDialog,
[Dialog.EditNode]: EditorEditDialog, [Dialog.EditNode]: EditorEditDialog,
[Dialog.TagSidebar]: TagSidebar,
} as const; } as const;

View file

@ -1,9 +1,11 @@
import { ProfileSidebar } from "~/containers/sidebars/ProfileSidebar"; import { SettingsSidebar } from '~/containers/sidebars/ProfileSidebar';
import { TagSidebar } from '~/containers/sidebars/TagSidebar';
import { SidebarName } from "./index"; import { SidebarName } from './index';
export const sidebarComponents = { export const sidebarComponents = {
[SidebarName.Settings]: ProfileSidebar, [SidebarName.Settings]: SettingsSidebar,
[SidebarName.Tag]: TagSidebar,
}; };
export type SidebarComponents = typeof sidebarComponents; export type SidebarComponents = typeof sidebarComponents;

View file

@ -1,5 +1,6 @@
import { ProfileSidebar } from "~/containers/sidebars/ProfileSidebar"; import { SettingsSidebar } from '~/containers/sidebars/ProfileSidebar';
export enum SidebarName { export enum SidebarName {
Settings = "settings", Settings = 'settings',
Tag = 'tag',
} }

View file

@ -7,9 +7,9 @@ import { ProfileSidebarNotes } from '~/components/profile/ProfileSidebarNotes';
import { ProfileSidebarSettings } from '~/components/profile/ProfileSidebarSettings'; import { ProfileSidebarSettings } from '~/components/profile/ProfileSidebarSettings';
import { SidebarStack } from '~/components/sidebar/SidebarStack'; import { SidebarStack } from '~/components/sidebar/SidebarStack';
import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard'; import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard';
import { SidebarWrapper } from '~/components/sidebar/SidebarWrapper';
import { SidebarName } from '~/constants/sidebar'; import { SidebarName } from '~/constants/sidebar';
import { ProfileSidebarMenu } from '~/containers/profile/ProfileSidebarMenu'; import { ProfileSidebarMenu } from '~/containers/profile/ProfileSidebarMenu';
import { SidebarWrapper } from '~/containers/sidebars/SidebarWrapper';
import { useAuth } from '~/hooks/auth/useAuth'; import { useAuth } from '~/hooks/auth/useAuth';
import { useUser } from '~/hooks/auth/useUser'; import { useUser } from '~/hooks/auth/useUser';
import type { SidebarComponentProps } from '~/types/sidebar'; import type { SidebarComponentProps } from '~/types/sidebar';
@ -17,12 +17,12 @@ import type { SidebarComponentProps } from '~/types/sidebar';
const tabs = ['profile', 'bookmarks'] as const; const tabs = ['profile', 'bookmarks'] as const;
type TabName = typeof tabs[number]; type TabName = typeof tabs[number];
interface ProfileSidebarProps interface SettingsSidebarProps
extends SidebarComponentProps<SidebarName.Settings> { extends SidebarComponentProps<SidebarName.Settings> {
page?: TabName; page?: TabName;
} }
const ProfileSidebar: VFC<ProfileSidebarProps> = ({ const SettingsSidebar: VFC<SettingsSidebarProps> = ({
onRequestClose, onRequestClose,
page, page,
openSidebar, openSidebar,
@ -79,4 +79,4 @@ const ProfileSidebar: VFC<ProfileSidebarProps> = ({
); );
}; };
export { ProfileSidebar }; export { SettingsSidebar };

View file

@ -1,18 +1,20 @@
import React, { useMemo, VFC } from 'react'; import { useMemo, VFC } from 'react';
import { InfiniteScroll } from '~/components/containers/InfiniteScroll'; import { InfiniteScroll } from '~/components/containers/InfiniteScroll';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { LoaderCircle } from '~/components/input/LoaderCircle'; import { LoaderCircle } from '~/components/input/LoaderCircle';
import { SidebarStack } from '~/components/sidebar/SidebarStack'; import { SidebarStack } from '~/components/sidebar/SidebarStack';
import { SidebarStackCard } from '~/components/sidebar/SidebarStackCard';
import { SidebarWrapper } from '~/components/sidebar/SidebarWrapper';
import { TagSidebarList } from '~/components/sidebar/TagSidebarList'; import { TagSidebarList } from '~/components/sidebar/TagSidebarList';
import { Tag } from '~/components/tags/Tag'; import { Tag } from '~/components/tags/Tag';
import { SidebarWrapper } from '~/containers/sidebars/SidebarWrapper'; import { SidebarName } from '~/constants/sidebar';
import { useTagNodes } from '~/hooks/tag/useTagNodes'; import { useTagNodes } from '~/hooks/tag/useTagNodes';
import { DialogComponentProps } from '~/types/modal'; import { SidebarComponentProps } from '~/types/sidebar';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface TagSidebarProps extends DialogComponentProps { interface TagSidebarProps extends SidebarComponentProps<SidebarName.Tag> {
tag: string; tag: string;
} }
@ -23,26 +25,13 @@ const TagSidebar: VFC<TagSidebarProps> = ({ tag, onRequestClose }) => {
return ( return (
<SidebarWrapper onClose={onRequestClose}> <SidebarWrapper onClose={onRequestClose}>
<SidebarStack> <SidebarStack>
<SidebarStackCard
headerFeature="close"
title={<Tag tag={{ title }} />}
onBackPress={onRequestClose}
>
<div className={styles.wrap}> <div className={styles.wrap}>
<div className={styles.content}> <div className={styles.content}>
<div className={styles.head}>
<div className={styles.tag}>
<Tag tag={{ title }} size="big" />
</div>
{isLoading && (
<div className={styles.sync}>
<LoaderCircle size={20} />
</div>
)}
<div className={styles.close}>
<button onClick={onRequestClose}>
<Icon icon="close" size={32} />
</button>
</div>
</div>
{!nodes.length && !isLoading ? ( {!nodes.length && !isLoading ? (
<div className={styles.none}> <div className={styles.none}>
<Icon icon="sad" size={120} /> <Icon icon="sad" size={120} />
@ -54,12 +43,17 @@ const TagSidebar: VFC<TagSidebarProps> = ({ tag, onRequestClose }) => {
</div> </div>
</div> </div>
) : ( ) : (
<InfiniteScroll hasMore={hasMore} loadMore={loadMore} className={styles.list}> <InfiniteScroll
hasMore={hasMore}
loadMore={loadMore}
className={styles.list}
>
<TagSidebarList nodes={nodes} onClick={onRequestClose} /> <TagSidebarList nodes={nodes} onClick={onRequestClose} />
</InfiniteScroll> </InfiniteScroll>
)} )}
</div> </div>
</div> </div>
</SidebarStackCard>
</SidebarStack> </SidebarStack>
</SidebarWrapper> </SidebarWrapper>
); );

View file

@ -1,14 +1,14 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { apiDeleteNodeTag, apiPostNodeTags } from '~/api/node'; import { apiDeleteNodeTag, apiPostNodeTags } from '~/api/node';
import { Dialog } from '~/constants/modal';
import { useShowModal } from '~/hooks/modal/useShowModal';
import { useGetNodeRelated } from '~/hooks/node/useGetNodeRelated'; import { useGetNodeRelated } from '~/hooks/node/useGetNodeRelated';
import { useLoadNode } from '~/hooks/node/useLoadNode'; import { useLoadNode } from '~/hooks/node/useLoadNode';
import { ITag } from '~/types'; import { ITag } from '~/types';
import { useTagSidebar } from '../sidebar/useTagSidebar';
export const useNodeTags = (id: number) => { export const useNodeTags = (id: number) => {
const showModal = useShowModal(Dialog.TagSidebar); const openTagSidebar = useTagSidebar();
const { refresh: refreshRelated } = useGetNodeRelated(id); const { refresh: refreshRelated } = useGetNodeRelated(id);
const { update } = useLoadNode(id); const { update } = useLoadNode(id);
@ -22,7 +22,7 @@ export const useNodeTags = (id: number) => {
console.warn(error); console.warn(error);
} }
}, },
[id, update, refreshRelated] [id, update, refreshRelated],
); );
const onClick = useCallback( const onClick = useCallback(
@ -31,9 +31,9 @@ export const useNodeTags = (id: number) => {
return; return;
} }
showModal({ tag: tag.title }); openTagSidebar(tag.title);
}, },
[showModal, id] [openTagSidebar, id],
); );
const onDelete = useCallback( const onDelete = useCallback(
@ -46,7 +46,7 @@ export const useNodeTags = (id: number) => {
console.warn(e); console.warn(e);
} }
}, },
[id, update, refreshRelated] [id, update, refreshRelated],
); );
return { onDelete, onChange, onClick }; return { onDelete, onChange, onClick };

View file

@ -0,0 +1,20 @@
import { useCallback } from 'react';
import { SidebarName } from '~/constants/sidebar';
import { ITag } from '~/types';
import { useSidebar } from '~/utils/providers/SidebarProvider';
export const useTagSidebar = () => {
const { open } = useSidebar();
return useCallback(
(tag: string) => {
if (!tag) {
return;
}
open(SidebarName.Tag, { tag });
},
[open],
);
};

View file

@ -84,11 +84,14 @@ export const SidebarProvider = <T extends SidebarComponent>({
{children} {children}
{current && ( {current && (
<ModalWrapper onOverlayClick={close}> <ModalWrapper onOverlayClick={close}>
{createElement(sidebarComponents[current], { {createElement(
sidebarComponents[current] as any,
{
onRequestClose: close, onRequestClose: close,
openSidebar: open, openSidebar: open,
...omit(['sidebar'], router.query), ...omit(['sidebar'], router.query),
} as any)} } as any,
)}
</ModalWrapper> </ModalWrapper>
)} )}
</SidebarContext.Provider> </SidebarContext.Provider>