|
@@ -1,7 +1,8 @@
|
|
|
import React, {useEffect, useState, useRef} from 'react';
|
|
|
import Box from '@mui/material/Box';
|
|
|
import Modal from '@mui/material/Modal';
|
|
|
-import MenuItem from '@mui/material/MenuItem';
|
|
|
+import ListItem from '@mui/material/ListItem';
|
|
|
+import ListItemText from '@mui/material/ListItemText';
|
|
|
import Button from '@mui/material/Button';
|
|
|
import IconButton from '@mui/material/IconButton';
|
|
|
import Typography from '@mui/material/Typography';
|
|
@@ -14,7 +15,7 @@ import {UserAvatar} from '../components'
|
|
|
|
|
|
import { printStrReq } from "../helpers";
|
|
|
import {connect} from 'react-redux'
|
|
|
-import {actionSetUserInfo} from '../actions'
|
|
|
+import {actionSetUserInfo, actionSetUserPass} from '../actions'
|
|
|
|
|
|
|
|
|
const styleModalParrent = {
|
|
@@ -34,17 +35,241 @@ const styleModalParrent = {
|
|
|
}
|
|
|
|
|
|
|
|
|
+const PassModal = ({onСonfirm, minPass='2', char=false, bigChar=false, number=false, regError}) => {
|
|
|
+ const [open, setOpen] = useState(false);
|
|
|
+ const handleOpen = () => {
|
|
|
+ setOpen(true);
|
|
|
+ }
|
|
|
+ const handleClose = () => {
|
|
|
+ setOpen(false);
|
|
|
+ }
|
|
|
|
|
|
+ const [oldPass, setOldPass] = useState('')
|
|
|
+ const [oldPassBlur, setOldPassBlur] = useState(false)
|
|
|
+
|
|
|
|
|
|
-const ProfileModal = ({minLog='2', myProfile, onСonfirm, onModalOpen}) => {
|
|
|
+ const [pass, setPass] = useState('')
|
|
|
+ const [passBlur, setPassBlur] = useState(false)
|
|
|
+
|
|
|
+ const [pass2, setPass2] = useState('')
|
|
|
+ const [pass2Blur, setPass2Blur] = useState(false)
|
|
|
+
|
|
|
+
|
|
|
+ const [wrongAlert, setWrongAlert] = useState(false)
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (regError?.payload === null) {
|
|
|
+ setWrongAlert(true)
|
|
|
+ } else {
|
|
|
+ setWrongAlert(false)
|
|
|
+ }
|
|
|
+ },[regError])
|
|
|
+
|
|
|
+
|
|
|
+ const checkPass = (password) => {
|
|
|
+ if ( password.length >= minPass &&
|
|
|
+ !password.match(/\s/) &&
|
|
|
+ (char ? password.match(/[a-zа-яё]/) : true) &&
|
|
|
+ (bigChar ? password.match(/[A-ZА-ЯЁ]/) : true) &&
|
|
|
+ (number ? password.match(/[\d]/) : true) ) {
|
|
|
+ return true
|
|
|
+ } else {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const printPassReq = (password) => {
|
|
|
+ let str = ''
|
|
|
+ if (checkPass(password)) {
|
|
|
+ str += ' '
|
|
|
+ } else if (password.match(/\s/)) {
|
|
|
+ str += 'Пароль не должен содержать пробелы '
|
|
|
+ } else {
|
|
|
+ str += 'Пароль должен содержать: '
|
|
|
+ str += printStrReq(password, minPass) + ','
|
|
|
+ if (!(char ? password.match(/[a-zа-яё]/) : true)) {
|
|
|
+ str += ' строчные буквы,'
|
|
|
+ }
|
|
|
+ if (!(bigChar ? password.match(/[A-ZА-ЯЁ]/) : true)) {
|
|
|
+ str += ' прописные буквы,'
|
|
|
+ }
|
|
|
+ if (!(number ? password.match(/[\d]/) : true)) {
|
|
|
+ str += ' цифры,'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return str.slice(0, -1)
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Button variant="text" color="error" onClick={handleOpen} >
|
|
|
+ Новый пароль
|
|
|
+ </Button>
|
|
|
+
|
|
|
+ <Modal
|
|
|
+ hideBackdrop
|
|
|
+ open={open}
|
|
|
+ onClose={handleClose}
|
|
|
+ aria-labelledby="child-modal-title"
|
|
|
+ aria-describedby="child-modal-description"
|
|
|
+ >
|
|
|
+ <Box sx={{ ...styleModalParrent, width: '40%', maxWidth: '400px', }}>
|
|
|
+ <Box sx={{ display: 'flex', justifyContent: 'end' }}>
|
|
|
+ <IconButton aria-label="delete" onClick={handleClose}>
|
|
|
+ <CloseIcon />
|
|
|
+ </IconButton>
|
|
|
+ </Box>
|
|
|
+
|
|
|
+ <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', mt: 4 }}>
|
|
|
+ <Typography variant="body1">
|
|
|
+ Введите старый пароль
|
|
|
+ </Typography>
|
|
|
+ <TextField
|
|
|
+ onChange={(e) => {
|
|
|
+ e.target.value = e.target.value.trim()
|
|
|
+ setOldPass(e.target.value.trim())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ onBlur={() => {
|
|
|
+ setOldPassBlur(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ onFocus={() => {
|
|
|
+ setOldPassBlur(false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ error={oldPassBlur ? (checkPass(oldPass) ? false : true) : false}
|
|
|
+ helperText={printPassReq(oldPass)}
|
|
|
+
|
|
|
+ inputProps={{
|
|
|
+ maxLength: 100
|
|
|
+ }}
|
|
|
+ required
|
|
|
+ variant="standard"
|
|
|
+ margin="none"
|
|
|
+ fullWidth
|
|
|
+ name="password"
|
|
|
+ label=""
|
|
|
+ type="password"
|
|
|
+ id="oldPasswordUser"
|
|
|
+ sx={{mt: 1}}
|
|
|
+ />
|
|
|
+ </Box>
|
|
|
+
|
|
|
+ <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', mt: 4 }}>
|
|
|
+ <Typography variant="body1">
|
|
|
+ Введите новый пароль
|
|
|
+ </Typography>
|
|
|
+ <TextField
|
|
|
+ onChange={(e) => {
|
|
|
+ e.target.value = e.target.value.trim()
|
|
|
+ setPass(e.target.value.trim())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ onBlur={() => {
|
|
|
+ setPassBlur(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ onFocus={() => {
|
|
|
+ setPassBlur(false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ error={passBlur ? (checkPass(pass) ? false : true) : false}
|
|
|
+ helperText={printPassReq(pass)}
|
|
|
+
|
|
|
+ inputProps={{
|
|
|
+ maxLength: 100
|
|
|
+ }}
|
|
|
+ required
|
|
|
+ variant="standard"
|
|
|
+ margin="none"
|
|
|
+ fullWidth
|
|
|
+ name="password"
|
|
|
+ label=""
|
|
|
+ type="password"
|
|
|
+ id="passwordUser"
|
|
|
+ sx={{mt: 1}}
|
|
|
+ />
|
|
|
+ </Box>
|
|
|
+
|
|
|
+ <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', mt: 4 }}>
|
|
|
+ <Typography variant="body1">
|
|
|
+ Повторите новый пароль
|
|
|
+ </Typography>
|
|
|
+ <TextField
|
|
|
+ onChange={(e) => {
|
|
|
+ e.target.value = e.target.value.trim()
|
|
|
+ setPass2(e.target.value.trim())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ onBlur={() => {
|
|
|
+ setPass2Blur(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ onFocus={() => {
|
|
|
+ setPass2Blur(false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ error={pass2Blur ? (checkPass(pass2) ? false : true) : false}
|
|
|
+ helperText={printPassReq(pass2)}
|
|
|
+
|
|
|
+ inputProps={{
|
|
|
+ maxLength: 100
|
|
|
+ }}
|
|
|
+ required
|
|
|
+ variant="standard"
|
|
|
+ margin="none"
|
|
|
+ fullWidth
|
|
|
+ name="password"
|
|
|
+ label=""
|
|
|
+ type="password"
|
|
|
+ id="passwordUser2"
|
|
|
+ sx={{mt: 1}}
|
|
|
+ />
|
|
|
+ </Box>
|
|
|
+
|
|
|
+
|
|
|
+ { wrongAlert ?
|
|
|
+ <Typography component="p" variant="body2" mt={1} ml={2}
|
|
|
+ sx={{fontWeight: 'medium', fontSize: '0.75rem', color: '#d32f2f'}}>
|
|
|
+ Неверный пароль
|
|
|
+ </Typography> :
|
|
|
+ <></>
|
|
|
+ }
|
|
|
+
|
|
|
+ <Box sx={{ display: 'flex', justifyContent: 'end', mt: 2}}>
|
|
|
+ <Button variant="contained"
|
|
|
+ disabled={( checkPass(oldPass) &&
|
|
|
+ checkPass(pass) &&
|
|
|
+ pass === pass2 ) ? false : true}
|
|
|
+
|
|
|
+ onClick={() => onСonfirm(oldPass, pass)}>
|
|
|
+ Изменить
|
|
|
+ </Button>
|
|
|
+ </Box>
|
|
|
+
|
|
|
+ </Box>
|
|
|
+ </Modal>
|
|
|
+ </>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ const CPassModal = connect( (state) => ({regError: state.promise.changePass || {}}),
|
|
|
+ {onСonfirm : actionSetUserPass})(PassModal)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const ProfileModal = ({minLog='2', myProfile, onСonfirm, logError}) => {
|
|
|
const [open, setOpen] = useState(false)
|
|
|
- // console.log(myProfile)
|
|
|
// const {login, nick, avatar: {url}} = myProfile
|
|
|
|
|
|
const [login, setLogin] = useState(myProfile.login)
|
|
|
const [logBlur, setLogBlur] = useState(false)
|
|
|
const [nick, setNick] = useState(myProfile.nick)
|
|
|
- const currAvatar = useRef(myProfile.avatar?.url)
|
|
|
|
|
|
const [img, setImg] = useState(null)
|
|
|
const {
|
|
@@ -61,13 +286,23 @@ const ProfileModal = ({minLog='2', myProfile, onСonfirm, onModalOpen}) => {
|
|
|
});
|
|
|
|
|
|
const handleOpen = () => setOpen(true)
|
|
|
- const handleClose = () => (setImg(null), setOpen(false))
|
|
|
+ const handleClose = () => (setOpen(false))
|
|
|
+
|
|
|
+ const [wrongAlert, setWrongAlert] = useState(false)
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (logError?.payload === null) {
|
|
|
+ setWrongAlert(true)
|
|
|
+ } else {
|
|
|
+ setWrongAlert(false)
|
|
|
+ }
|
|
|
+ },[logError])
|
|
|
|
|
|
return (
|
|
|
<div>
|
|
|
- <MenuItem onClick={handleOpen}>
|
|
|
- Профиль
|
|
|
- </MenuItem>
|
|
|
+ <ListItem button onClick={handleOpen} >
|
|
|
+ <ListItemText primary={'Мой профиль'} />
|
|
|
+ </ListItem>
|
|
|
|
|
|
<Modal
|
|
|
open={open}
|
|
@@ -91,15 +326,17 @@ const ProfileModal = ({minLog='2', myProfile, onСonfirm, onModalOpen}) => {
|
|
|
|
|
|
<Box sx={{ display: 'flex', justifyContent: 'start', mt: 2, }}>
|
|
|
|
|
|
- <UserAvatar profile={{ login: login, nick: nick, avatar: {url: myProfile.avatar?.url || ''},
|
|
|
- localUrl: img && URL.createObjectURL(img)}} />
|
|
|
|
|
|
<form action="/upload" method="post" encType="multipart/form-data" id='formUser'>
|
|
|
<section className="container">
|
|
|
- <div {...getRootProps({className: 'dropzone'})}>
|
|
|
+ <Box {...getRootProps({className: 'dropzone'})} sx={{ cursor: 'pointer', height: '70px', display: 'flex' }} >
|
|
|
+
|
|
|
+ <UserAvatar profile={{ login: login, nick: nick, avatar: {url: myProfile.avatar?.url || ''},
|
|
|
+ localUrl: img && URL.createObjectURL(img)}} bigSize={true} />
|
|
|
+
|
|
|
<input {...getInputProps()} type="file" name="media" id='mediaUser' />
|
|
|
- <p>Изменить аватар</p>
|
|
|
- </div>
|
|
|
+ <Box sx={{ p: '20px', ml: 1 }} >Изменить аватар</Box>
|
|
|
+ </Box>
|
|
|
</section>
|
|
|
</form>
|
|
|
|
|
@@ -164,11 +401,17 @@ const ProfileModal = ({minLog='2', myProfile, onСonfirm, onModalOpen}) => {
|
|
|
|
|
|
|
|
|
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 4 }}>
|
|
|
- <Button variant="text" color="error" >
|
|
|
- Новый пароль
|
|
|
- </Button>
|
|
|
+ <CPassModal />
|
|
|
</Box>
|
|
|
|
|
|
+ { wrongAlert ?
|
|
|
+ <Typography component="p" variant="body2" mt={2} ml={2}
|
|
|
+ sx={{fontWeight: 'medium', fontSize: '0.75rem', color: '#d32f2f'}}>
|
|
|
+ Логин уже существует
|
|
|
+ </Typography> :
|
|
|
+ <></>
|
|
|
+ }
|
|
|
+
|
|
|
<Box sx={{ display: 'flex', justifyContent: 'end', mt: 2}}>
|
|
|
<Button variant="contained"
|
|
|
disabled={(login?.length >= minLog) ? false : true}
|
|
@@ -183,7 +426,8 @@ const ProfileModal = ({minLog='2', myProfile, onСonfirm, onModalOpen}) => {
|
|
|
</div>
|
|
|
);
|
|
|
}
|
|
|
-export const CProfileModal = connect( state => ({myProfile: state.promise?.myProfile?.payload || {}}),
|
|
|
+export const CProfileModal = connect( state => ( { myProfile: state.promise?.myProfile?.payload || {},
|
|
|
+ logError: state.promise.updateUser || {} }),
|
|
|
{onСonfirm : actionSetUserInfo})(ProfileModal)
|
|
|
|
|
|
|