mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
added empty profile sidebar
This commit is contained in:
parent
7f7c12df2b
commit
0c9d5467ed
12 changed files with 138 additions and 43 deletions
|
@ -5,11 +5,14 @@ import markdown from '~/styles/common/markdown.module.scss';
|
||||||
import { Group } from '~/components/containers/Group';
|
import { Group } from '~/components/containers/Group';
|
||||||
import { Button } from '~/components/input/Button';
|
import { Button } from '~/components/input/Button';
|
||||||
import { InputText } from '~/components/input/InputText';
|
import { InputText } from '~/components/input/InputText';
|
||||||
|
import { useShowModal } from '~/hooks/modal/useShowModal';
|
||||||
|
import { Dialog } from '~/constants/modal';
|
||||||
|
|
||||||
interface IProps {}
|
interface IProps {}
|
||||||
|
|
||||||
const BorisUIDemo: FC<IProps> = () => {
|
const BorisUIDemo: FC<IProps> = () => {
|
||||||
const [text, setText] = useState('');
|
const [text, setText] = useState('');
|
||||||
|
const openProfileSidebar = useShowModal(Dialog.ProfileSidebar);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={styles.card}>
|
<Card className={styles.card}>
|
||||||
|
@ -20,6 +23,9 @@ const BorisUIDemo: FC<IProps> = () => {
|
||||||
разработке
|
разработке
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2>Тестовые фичи</h2>
|
||||||
|
<Button onClick={() => openProfileSidebar({})}>Профиль в сайдбаре</Button>
|
||||||
|
|
||||||
<h2>Инпуты</h2>
|
<h2>Инпуты</h2>
|
||||||
|
|
||||||
<form autoComplete="off">
|
<form autoComplete="off">
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
:global(.swiper-button-next),
|
:global(.swiper-button-next),
|
||||||
:global(.swiper-button-prev) {
|
:global(.swiper-button-prev) {
|
||||||
|
@include outer_shadow;
|
||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
|
|
|
@ -2,17 +2,17 @@ import React, { ChangeEvent, FC, useCallback } from 'react';
|
||||||
import styles from './styles.module.scss';
|
import styles from './styles.module.scss';
|
||||||
import { getURL } from '~/utils/dom';
|
import { getURL } from '~/utils/dom';
|
||||||
import { PRESETS } from '~/constants/urls';
|
import { PRESETS } from '~/constants/urls';
|
||||||
import { Icon } from '~/components/input/Icon';
|
|
||||||
import { IFile } from '~/types';
|
import { IFile } from '~/types';
|
||||||
import { Button } from '~/components/input/Button';
|
import { Button } from '~/components/input/Button';
|
||||||
|
|
||||||
export interface ProfileAvatarProps {
|
export interface ProfileAvatarProps {
|
||||||
|
size?: number;
|
||||||
canEdit: boolean;
|
canEdit: boolean;
|
||||||
photo?: IFile;
|
photo?: IFile;
|
||||||
onChangePhoto: (file: File) => void;
|
onChangePhoto: (file: File) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProfileAvatar: FC<ProfileAvatarProps> = ({ photo, onChangePhoto, canEdit }) => {
|
const ProfileAvatar: FC<ProfileAvatarProps> = ({ photo, onChangePhoto, canEdit, size }) => {
|
||||||
const onInputChange = useCallback(
|
const onInputChange = useCallback(
|
||||||
async (event: ChangeEvent<HTMLInputElement>) => {
|
async (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
if (!event.target.files?.length) {
|
if (!event.target.files?.length) {
|
||||||
|
@ -31,6 +31,8 @@ const ProfileAvatar: FC<ProfileAvatarProps> = ({ photo, onChangePhoto, canEdit }
|
||||||
className={styles.avatar}
|
className={styles.avatar}
|
||||||
style={{
|
style={{
|
||||||
backgroundImage,
|
backgroundImage,
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{canEdit && <input type="file" onInput={onInputChange} />}
|
{canEdit && <input type="file" onInput={onInputChange} />}
|
||||||
|
|
|
@ -8,10 +8,8 @@
|
||||||
height: 100px;
|
height: 100px;
|
||||||
background: $content_bg 50% 50% no-repeat;
|
background: $content_bg 50% 50% no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: $gap;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { PhotoSwipe } from '~/containers/dialogs/PhotoSwipe';
|
||||||
import { EditorCreateDialog } from '~/containers/dialogs/EditorCreateDialog';
|
import { EditorCreateDialog } from '~/containers/dialogs/EditorCreateDialog';
|
||||||
import { EditorEditDialog } from '~/containers/dialogs/EditorEditDialog';
|
import { EditorEditDialog } from '~/containers/dialogs/EditorEditDialog';
|
||||||
import { TagSidebar } from '~/containers/sidebars/TagSidebar';
|
import { TagSidebar } from '~/containers/sidebars/TagSidebar';
|
||||||
|
import { ProfileSidebar } from '~/containers/sidebars/ProfileSidebar';
|
||||||
|
|
||||||
export enum Dialog {
|
export enum Dialog {
|
||||||
Login = 'Login',
|
Login = 'Login',
|
||||||
|
@ -22,6 +23,7 @@ export enum Dialog {
|
||||||
CreateNode = 'CreateNode',
|
CreateNode = 'CreateNode',
|
||||||
EditNode = 'EditNode',
|
EditNode = 'EditNode',
|
||||||
TagSidebar = 'TagNodes',
|
TagSidebar = 'TagNodes',
|
||||||
|
ProfileSidebar = 'ProfileSidebar',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DIALOG_CONTENT = {
|
export const DIALOG_CONTENT = {
|
||||||
|
@ -36,4 +38,5 @@ export const DIALOG_CONTENT = {
|
||||||
[Dialog.CreateNode]: EditorCreateDialog,
|
[Dialog.CreateNode]: EditorCreateDialog,
|
||||||
[Dialog.EditNode]: EditorEditDialog,
|
[Dialog.EditNode]: EditorEditDialog,
|
||||||
[Dialog.TagSidebar]: TagSidebar,
|
[Dialog.TagSidebar]: TagSidebar,
|
||||||
|
[Dialog.ProfileSidebar]: ProfileSidebar,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -27,7 +27,9 @@ const ProfileInfo: FC<IProps> = ({ isOwn }) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Group className={styles.wrap} horizontal>
|
<Group className={styles.wrap} horizontal>
|
||||||
|
<div className={styles.avatar}>
|
||||||
<ProfileAvatar canEdit={isOwn} onChangePhoto={updatePhoto} photo={photo} />
|
<ProfileAvatar canEdit={isOwn} onChangePhoto={updatePhoto} photo={photo} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={styles.field}>
|
<div className={styles.field}>
|
||||||
<div className={styles.name}>
|
<div className={styles.name}>
|
||||||
|
|
|
@ -8,13 +8,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
@include outer_shadow();
|
|
||||||
|
|
||||||
border-radius: $radius;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
background: $content_bg 50% 50% no-repeat;
|
|
||||||
background-size: cover;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: $gap;
|
left: $gap;
|
||||||
|
|
25
src/containers/profile/ProfileSidebarHead/index.tsx
Normal file
25
src/containers/profile/ProfileSidebarHead/index.tsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import React, { VFC } from 'react';
|
||||||
|
import { Group } from '~/components/containers/Group';
|
||||||
|
import { Filler } from '~/components/containers/Filler';
|
||||||
|
import { ProfileAvatar } from '~/components/profile/ProfileAvatar';
|
||||||
|
import { usePatchUser } from '~/hooks/auth/usePatchUser';
|
||||||
|
import { useUser } from '~/hooks/auth/useUser';
|
||||||
|
|
||||||
|
interface ProfileSidebarHeadProps {}
|
||||||
|
|
||||||
|
const ProfileSidebarHead: VFC<ProfileSidebarHeadProps> = () => {
|
||||||
|
const { user } = useUser();
|
||||||
|
const { updatePhoto } = usePatchUser();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Group horizontal>
|
||||||
|
<ProfileAvatar canEdit onChangePhoto={updatePhoto} photo={user.photo} size={72} />
|
||||||
|
|
||||||
|
<Filler>
|
||||||
|
<h2>{user.fullname || user.username}</h2>
|
||||||
|
</Filler>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { ProfileSidebarHead };
|
39
src/containers/sidebars/ProfileSidebar/index.tsx
Normal file
39
src/containers/sidebars/ProfileSidebar/index.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import React, { VFC } from 'react';
|
||||||
|
import { SidebarWrapper } from '~/containers/sidebars/SidebarWrapper';
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
import { DialogComponentProps } from '~/types/modal';
|
||||||
|
import markdown from '~/styles/common/markdown.module.scss';
|
||||||
|
import { Button } from '~/components/input/Button';
|
||||||
|
import { Filler } from '~/components/containers/Filler';
|
||||||
|
import { ProfileSidebarHead } from '~/containers/profile/ProfileSidebarHead';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
interface ProfileSidebarProps extends DialogComponentProps {}
|
||||||
|
|
||||||
|
const ProfileSidebar: VFC<ProfileSidebarProps> = ({ onRequestClose }) => {
|
||||||
|
return (
|
||||||
|
<SidebarWrapper onClose={onRequestClose}>
|
||||||
|
<div className={styles.wrap}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<div>
|
||||||
|
<ProfileSidebarHead />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Filler className={classNames(markdown.wrapper, styles.text)}>
|
||||||
|
<h3>Здесь будет профиль</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Но пока что мы просто тестируем как это будет выглядеть и будет ли это удобнее модалки
|
||||||
|
</p>
|
||||||
|
</Filler>
|
||||||
|
|
||||||
|
<Button round onClick={onRequestClose} color="secondary">
|
||||||
|
Закрыть
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SidebarWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { ProfileSidebar };
|
22
src/containers/sidebars/ProfileSidebar/styles.module.scss
Normal file
22
src/containers/sidebars/ProfileSidebar/styles.module.scss
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
@import "src/styles/variables";
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
@include sidebar_content(400px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
border-radius: $radius;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
min-height: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
padding: $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
margin-top: $gap * 2;
|
||||||
|
}
|
|
@ -128,3 +128,36 @@ button {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h5, h4, h3, h2, h1 {
|
||||||
|
color: white;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: $gap;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -53,17 +53,7 @@ $margin: 1em;
|
||||||
margin-bottom: $margin;
|
margin-bottom: $margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: $margin;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h5, h4, h3, h2, h1 {
|
h5, h4, h3, h2, h1 {
|
||||||
color: white;
|
|
||||||
font-weight: 800;
|
|
||||||
line-height: 1.2em;
|
line-height: 1.2em;
|
||||||
margin: $margin * 1.5 0 $margin / 2;
|
margin: $margin * 1.5 0 $margin / 2;
|
||||||
|
|
||||||
|
@ -72,26 +62,6 @@ $margin: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 1.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 1.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
list-style: disc;
|
list-style: disc;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue