HM-118 Добавил возможность менять аватарку пользователя и походу еще … (#58)
* HM-118 Добавил возможность менять аватарку пользователя и походу еще зацепил HM-117 где нужно было поменять способ получения инфы о пользователе
This commit is contained in:
@ -31,6 +31,21 @@ class UsersService {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMe = async () => {
|
||||||
|
const {data} = await http.get(`${ROOT_URL}/me`);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAvatar = async (avatar, updateOptions) => {
|
||||||
|
const {data} = await http.post(`${ROOT_URL}/edit-me`, {...updateOptions, avatar});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
changePassword = async (password, updateOptions) => {
|
||||||
|
const {data} = await http.post(`${ROOT_URL}/edit-me`, {...updateOptions, password});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод поиска пользователя по Логину
|
* Метод поиска пользователя по Логину
|
||||||
* @param {string} login - Логин пользователя
|
* @param {string} login - Логин пользователя
|
||||||
|
|||||||
@ -116,9 +116,9 @@
|
|||||||
<div class="Password__inputContainer m-1" id="newpassrepeat"></div>
|
<div class="Password__inputContainer m-1" id="newpassrepeat"></div>
|
||||||
<button type="button" class="Profile__button btn btn-outline-primary mt-3">Сохранить</button>
|
<button type="button" class="Profile__button btn btn-outline-primary mt-3">Сохранить</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-2 flex-grow-4">
|
<div class="p-2 flex-grow-4 Profile__avatar-container">
|
||||||
<img src="./img/ava.jpg" class="Profile__avatar m-2" alt="avatar">
|
<img src="./img/ava.jpg" class="Profile__avatar m-2" alt="avatar">
|
||||||
<div class="h6 text-center">login_name</div>
|
<div class="h6 text-center Profile__user-name">login_name</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
12
src/components/avatar-modal-component/AvatarModal.css
Normal file
12
src/components/avatar-modal-component/AvatarModal.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.Avatar__img {
|
||||||
|
width: 100%;
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
max-height: 400px;
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
.Avatar__container {
|
||||||
|
padding: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
75
src/components/avatar-modal-component/AvatarModal.js
Normal file
75
src/components/avatar-modal-component/AvatarModal.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import Modal from '../modal/Modal';
|
||||||
|
import {createElement} from '../../utils/elementUtils';
|
||||||
|
import FormControl from '../form-control/index';
|
||||||
|
import './AvatarModal.css';
|
||||||
|
import usersServiceApi from '../../api/UsersServiceAPI';
|
||||||
|
import userInfoService from '../../services/UserInfoService';
|
||||||
|
import {EVENTS} from '../../consts';
|
||||||
|
|
||||||
|
class AvatarModal extends Modal {
|
||||||
|
constructor (parentNode) {
|
||||||
|
super(parentNode);
|
||||||
|
|
||||||
|
this.header.textContent = 'Основное изображение';
|
||||||
|
this.avatar = createElement({
|
||||||
|
tagName: 'div',
|
||||||
|
options: {
|
||||||
|
className: 'Avatar__img',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.width = this.avatar.scrollWidth;
|
||||||
|
this.content.append(this.avatar);
|
||||||
|
this.content.className = 'Avatar__container';
|
||||||
|
|
||||||
|
this.input = this.createComponent(FormControl, this.content, {
|
||||||
|
id: 'avatar-url-input',
|
||||||
|
label: 'URL нового изображения',
|
||||||
|
placeholder: 'Введите URL',
|
||||||
|
className: 'Avatar__url-input'
|
||||||
|
});
|
||||||
|
|
||||||
|
this.submitBtn = createElement({
|
||||||
|
tagName: 'button',
|
||||||
|
options: {
|
||||||
|
className: 'Avatar__submit-btn btn btn-outline-primary'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.submitBtn.textContent = 'Применить';
|
||||||
|
this.footer.append(this.submitBtn);
|
||||||
|
this.addEventListener(this.submitBtn, EVENTS.CLICK, () => {
|
||||||
|
this.submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addSubscribe(this.input, 'input', (evt) => {
|
||||||
|
this.url = evt.currentTarget.value;
|
||||||
|
this.changeAvatar(this.url);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
changeAvatar (url) {
|
||||||
|
this.avatar.style.backgroundImage = `url(${url})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
init = async () => {
|
||||||
|
const user = await usersServiceApi.getMe();
|
||||||
|
this.changeAvatar(this.url || user.avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
openEditor () {
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
submit = async () => {
|
||||||
|
if (this.url) {
|
||||||
|
await usersServiceApi.setAvatar(this.url);
|
||||||
|
userInfoService.setUserLogin();
|
||||||
|
this.hide();
|
||||||
|
} else {
|
||||||
|
this.input.input.placeholder = 'Вы не ввели URL';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default AvatarModal;
|
||||||
@ -36,6 +36,9 @@ class FormControl extends Component {
|
|||||||
this.addEventListener(this.input, 'focus', this.clearError);
|
this.addEventListener(this.input, 'focus', this.clearError);
|
||||||
this.addEventListener(this.input, 'click', this.clearError);
|
this.addEventListener(this.input, 'click', this.clearError);
|
||||||
this.addEventListener(this.input, 'keydown', this.clearError);
|
this.addEventListener(this.input, 'keydown', this.clearError);
|
||||||
|
this.addEventListener(this.input, 'input', (evt) => {
|
||||||
|
this.next('input', evt);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
disabled = (value) => {
|
disabled = (value) => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Component from '../component/Component';
|
import Component from '../component/Component';
|
||||||
import FormControl from '../form-control';
|
import FormControl from '../form-control';
|
||||||
import {FORM_TYPES} from '../../consts';
|
import {FORM_TYPES, EVENTS} from '../../consts';
|
||||||
|
|
||||||
class ProfileContent extends Component {
|
class ProfileContent extends Component {
|
||||||
constructor (parentNode) {
|
constructor (parentNode) {
|
||||||
@ -10,6 +10,11 @@ class ProfileContent extends Component {
|
|||||||
this.Password = this.mainNode.querySelector('.Password__inputContainer');
|
this.Password = this.mainNode.querySelector('.Password__inputContainer');
|
||||||
this.profileButton = this.mainNode.querySelector('.Profile__button');
|
this.profileButton = this.mainNode.querySelector('.Profile__button');
|
||||||
this.title.textContent = 'Смена пароля';
|
this.title.textContent = 'Смена пароля';
|
||||||
|
this.avatar = this.mainNode.querySelector('.Profile__avatar');
|
||||||
|
this.addEventListener(this.avatar, EVENTS.CLICK, () => {
|
||||||
|
this.next(EVENTS.OPEN_MODAL);
|
||||||
|
});
|
||||||
|
this.userName = this.mainNode.querySelector('.Profile__user-name');
|
||||||
this.oldPassword = this.createComponent(FormControl, this.Password, {
|
this.oldPassword = this.createComponent(FormControl, this.Password, {
|
||||||
label: 'Старый пароль:',
|
label: 'Старый пароль:',
|
||||||
id: 'oldpass',
|
id: 'oldpass',
|
||||||
@ -32,7 +37,12 @@ class ProfileContent extends Component {
|
|||||||
required: true,
|
required: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addEventListener(this.form, 'submit', this.submit);
|
this.addEventListener(this.form, EVENTS.SUBMIT, this.submit);
|
||||||
|
}
|
||||||
|
|
||||||
|
initProfile (user) {
|
||||||
|
this.avatar.src = user.avatar;
|
||||||
|
this.userName.textContent = user.login;
|
||||||
}
|
}
|
||||||
|
|
||||||
disabled = (value) => {
|
disabled = (value) => {
|
||||||
|
|||||||
@ -1,12 +1,30 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/index';
|
||||||
import ProfileContent from '../profile-content';
|
import ProfileContent from '../profile-content';
|
||||||
import './ProfilePage.css';
|
import './ProfilePage.css';
|
||||||
|
import usersServiceApi from '../../api/UsersServiceAPI';
|
||||||
|
import AvatarModal from '../avatar-modal-component/AvatarModal';
|
||||||
|
import userInfoService from '../../services/UserInfoService';
|
||||||
|
import {EVENTS} from '../../consts';
|
||||||
|
|
||||||
class ProfilePage extends Component {
|
class ProfilePage extends Component {
|
||||||
constructor (mainNodeSelector, parentNode) {
|
constructor (mainNodeSelector, parentNode) {
|
||||||
super(mainNodeSelector, parentNode);
|
super(mainNodeSelector, parentNode);
|
||||||
this.form = this.createComponent(ProfileContent, this.mainNode);
|
this.form = this.createComponent(ProfileContent, this.mainNode);
|
||||||
|
this.modal = this.createComponent(AvatarModal, this.mainNode);
|
||||||
|
this.addSubscribe(this.form, EVENTS.OPEN_MODAL, () => {
|
||||||
|
this.modal.openEditor();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
|
||||||
|
this.addSubscribe(userInfoService, EVENTS.CHANGE_USER_INFO, () => {
|
||||||
|
this.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
init = async () => {
|
||||||
|
this.user = await usersServiceApi.getMe();
|
||||||
|
this.form.initProfile(this.user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,6 +52,10 @@ export const EVENTS = {
|
|||||||
ROW_CLICK: 'rowClick',
|
ROW_CLICK: 'rowClick',
|
||||||
ROW_DOUBLE_CLICK: 'rowDoubleClick',
|
ROW_DOUBLE_CLICK: 'rowDoubleClick',
|
||||||
CHANGE_USER_INFO: 'changeUserInfo',
|
CHANGE_USER_INFO: 'changeUserInfo',
|
||||||
|
CHANGE_USER_AVATAR: 'changeUserAvatar',
|
||||||
|
OPEN_MODAL: 'openModal',
|
||||||
|
CLICK: 'click',
|
||||||
|
SUBMIT: 'submit'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FORM_TYPES = {
|
export const FORM_TYPES = {
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
import usersServiceApi from '../api/UsersServiceAPI';
|
import usersServiceApi from '../api/UsersServiceAPI';
|
||||||
import tokenApi from '../api/TokenAPI';
|
|
||||||
import {parseJwt} from '../utils/jwtDecode';
|
|
||||||
import {EVENTS} from '../consts';
|
import {EVENTS} from '../consts';
|
||||||
import EmitService from './EmitService';
|
import EmitService from './EmitService';
|
||||||
|
|
||||||
@ -15,10 +13,13 @@ class UserInfoService extends EmitService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setUserLogin = async () => {
|
setUserLogin = async () => {
|
||||||
const {login} = parseJwt(tokenApi.getAccessToken());
|
this.userInfo = await usersServiceApi.getMe();
|
||||||
this.userInfo = await usersServiceApi.find(login);
|
|
||||||
this.next(EVENTS.CHANGE_USER_INFO, {...this.userInfo});
|
this.next(EVENTS.CHANGE_USER_INFO, {...this.userInfo});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeAllAvatars () {
|
||||||
|
this.next(EVENTS.CHANGE_USER_AVATAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const userInfoService = new UserInfoService();
|
const userInfoService = new UserInfoService();
|
||||||
|
|||||||
Reference in New Issue
Block a user