2022-10-13 14:31:11 +05:00
|
|
|
|
import { memo, ReactNode, useCallback, useState } from 'react'
|
2022-06-09 17:51:41 +05:00
|
|
|
|
import { useNavigate, useLocation } from 'react-router-dom'
|
2022-10-13 14:31:11 +05:00
|
|
|
|
import { Button, Collapse, Drawer, DrawerProps, Form, FormRule, Input, Popconfirm } from 'antd'
|
|
|
|
|
import { useForm } from 'antd/lib/form/Form'
|
2021-12-27 18:06:26 +05:00
|
|
|
|
|
2022-10-13 14:31:11 +05:00
|
|
|
|
import { useUser } from '@asb/context'
|
|
|
|
|
import { Grid, GridItem } from '@components/Grid'
|
|
|
|
|
import LoaderPortal from '@components/LoaderPortal'
|
|
|
|
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
|
|
|
|
import { isURLAvailable, removeUser } from '@utils'
|
|
|
|
|
import { AuthService } from '@api'
|
2022-06-09 17:51:41 +05:00
|
|
|
|
|
2022-12-08 12:13:58 +05:00
|
|
|
|
import '@styles/components/user_menu.less'
|
2021-12-02 15:21:10 +05:00
|
|
|
|
|
2022-10-13 14:31:11 +05:00
|
|
|
|
export type UserMenuProps = DrawerProps & {
|
|
|
|
|
isAdmin?: boolean
|
|
|
|
|
additional?: ReactNode
|
|
|
|
|
}
|
2021-12-02 15:49:41 +05:00
|
|
|
|
|
2022-10-13 14:31:11 +05:00
|
|
|
|
type ChangePasswordForm = {
|
|
|
|
|
'new-password': string
|
|
|
|
|
}
|
2021-12-02 15:21:10 +05:00
|
|
|
|
|
2022-10-13 14:31:11 +05:00
|
|
|
|
const newPasswordRules: FormRule[] = [{ required: true, message: 'Пожалуйста, введите новый пароль!' }]
|
|
|
|
|
|
|
|
|
|
const confirmPasswordRules: FormRule[] = [({ getFieldValue }) => ({ validator(_, value: string) {
|
|
|
|
|
if (value !== getFieldValue('new-password'))
|
|
|
|
|
return Promise.reject('Пароли не совпадают!')
|
|
|
|
|
return Promise.resolve()
|
|
|
|
|
}})]
|
|
|
|
|
|
|
|
|
|
export const UserMenu = memo<UserMenuProps>(({ isAdmin, additional, ...other }) => {
|
|
|
|
|
const [showLoader, setShowLoader] = useState<boolean>(false)
|
|
|
|
|
|
|
|
|
|
const [changeLoginForm] = useForm<ChangePasswordForm>()
|
2022-06-09 17:51:41 +05:00
|
|
|
|
const navigate = useNavigate()
|
2022-02-25 16:57:08 +05:00
|
|
|
|
const location = useLocation()
|
2022-10-13 14:31:11 +05:00
|
|
|
|
const user = useUser()
|
|
|
|
|
|
|
|
|
|
const navigateTo = useCallback((to: string) => navigate(to, { state: { from: location.pathname }}), [navigate, location.pathname])
|
2021-12-02 15:21:10 +05:00
|
|
|
|
|
2022-10-13 14:31:11 +05:00
|
|
|
|
const onChangePasswordOk = useCallback(() => invokeWebApiWrapperAsync(
|
|
|
|
|
async (values: any) => {
|
|
|
|
|
await AuthService.changePassword(user.id ?? -1, `${values['new-password']}`)
|
|
|
|
|
removeUser()
|
|
|
|
|
navigateTo('/login')
|
|
|
|
|
},
|
|
|
|
|
setShowLoader,
|
|
|
|
|
`Не удалось сменить пароль пользователя ${user.login}`,
|
|
|
|
|
{ actionName: 'Смена пароля пользователя' },
|
|
|
|
|
), [navigateTo])
|
2021-12-02 15:21:10 +05:00
|
|
|
|
|
2022-10-13 14:31:11 +05:00
|
|
|
|
const logout = useCallback(() => {
|
|
|
|
|
removeUser()
|
|
|
|
|
navigateTo('/login')
|
|
|
|
|
}, [navigateTo])
|
2021-12-27 18:06:26 +05:00
|
|
|
|
|
2021-12-02 15:21:10 +05:00
|
|
|
|
return (
|
2022-10-13 14:31:11 +05:00
|
|
|
|
<Drawer
|
|
|
|
|
closable
|
|
|
|
|
placement={'left'}
|
|
|
|
|
className={'user-menu'}
|
|
|
|
|
title={'Профиль пользователя'}
|
|
|
|
|
{...other}
|
|
|
|
|
>
|
|
|
|
|
<div className={'profile-links'}>
|
|
|
|
|
{isAdmin ? (
|
|
|
|
|
<Button onClick={() => navigateTo('/')}>Вернуться на сайт</Button>
|
|
|
|
|
) : isURLAvailable('/admin') && (
|
|
|
|
|
<Button onClick={() => navigateTo('/admin')}>Панель администратора</Button>
|
2021-12-02 15:21:10 +05:00
|
|
|
|
)}
|
2022-10-13 14:31:11 +05:00
|
|
|
|
<Button type={'ghost'} onClick={logout}>Выход</Button>
|
|
|
|
|
</div>
|
|
|
|
|
<Collapse>
|
|
|
|
|
<Collapse.Panel header={'Данные'} key={'summary'}>
|
|
|
|
|
<Grid>
|
|
|
|
|
<GridItem row={1} col={1}>Логин:</GridItem>
|
|
|
|
|
<GridItem row={1} col={2}>{user.login}</GridItem>
|
|
|
|
|
<GridItem row={2} col={1}>Фамилия:</GridItem>
|
|
|
|
|
<GridItem row={2} col={2}>{user.surname}</GridItem>
|
|
|
|
|
<GridItem row={3} col={1}>Имя:</GridItem>
|
|
|
|
|
<GridItem row={3} col={2}>{user.name}</GridItem>
|
|
|
|
|
<GridItem row={4} col={1}>Отчество:</GridItem>
|
|
|
|
|
<GridItem row={4} col={2}>{user.patronymic}</GridItem>
|
|
|
|
|
<GridItem row={5} col={1}>E-mail:</GridItem>
|
|
|
|
|
<GridItem row={5} col={2}>{user.email}</GridItem>
|
|
|
|
|
</Grid>
|
|
|
|
|
</Collapse.Panel>
|
|
|
|
|
<Collapse.Panel header={'Смена пароля'} key={'change-password'}>
|
|
|
|
|
<LoaderPortal show={showLoader}>
|
|
|
|
|
<Form name={'change-password'} form={changeLoginForm} autoComplete={'off'} onFinish={onChangePasswordOk}>
|
|
|
|
|
<Form.Item name={'new-password'} label={'Новый пароль'} rules={newPasswordRules}>
|
|
|
|
|
<Input.Password placeholder={'Впишите новый пароль'} />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item required name={'confirm-password'} rules={confirmPasswordRules} label={'Подтверждение пароля'}>
|
|
|
|
|
<Input.Password />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item>
|
|
|
|
|
<Popconfirm title={'Вы уверены что хотите сменить пароль?'} onConfirm={changeLoginForm.submit} placement={'topRight'}>
|
|
|
|
|
<Button type={'primary'}>Сменить</Button>
|
|
|
|
|
</Popconfirm>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
</LoaderPortal>
|
|
|
|
|
</Collapse.Panel>
|
|
|
|
|
{additional}
|
|
|
|
|
</Collapse>
|
|
|
|
|
</Drawer>
|
2021-12-02 15:21:10 +05:00
|
|
|
|
)
|
2022-02-07 14:58:38 +05:00
|
|
|
|
})
|