diff --git a/index.html b/index.html
index 7f1484e..fce00b9 100644
--- a/index.html
+++ b/index.html
@@ -7,61 +7,8 @@
-
+
+ Загрузка ...
diff --git a/index.js b/index.js
index 3245e86..463e019 100644
--- a/index.js
+++ b/index.js
@@ -1,7 +1,3 @@
-import { fetchGetComments } from './modules/fetchGetComments.js';
-import { addClickBtnAddComment } from './modules/eventsBtnAddComment.js';
+import { renderComments } from './modules/renderComments.js';
-const API = 'https://wedev-api.sky.pro/api/v1/arusskov/comments';
-
-fetchGetComments(API);
-addClickBtnAddComment(API);
+renderComments();
diff --git a/modules/Login.js b/modules/Login.js
new file mode 100644
index 0000000..8726939
--- /dev/null
+++ b/modules/Login.js
@@ -0,0 +1,29 @@
+const hostLogin = 'https://wedev-api.sky.pro/api/user/login';
+
+export function Login(login, password) {
+ return fetch(hostLogin, {
+ method: 'POST',
+ body: JSON.stringify({ login, password }),
+ })
+ .then((response) => {
+ if (response.status === 201) {
+ return response.json();
+ } else {
+ if (response.status === 400) {
+ throw new Error('400');
+ } else {
+ throw new Error('Что то пошло не так');
+ }
+ }
+ })
+ .catch((error) => {
+ switch (error.message) {
+ case '400':
+ alert('Не верный логин или пароль');
+ break;
+ default:
+ alert('Что то пошло не так');
+ break;
+ }
+ });
+}
diff --git a/modules/api.js b/modules/api.js
new file mode 100644
index 0000000..20333ca
--- /dev/null
+++ b/modules/api.js
@@ -0,0 +1,54 @@
+import { user } from './user.js';
+
+const host = 'https://wedev-api.sky.pro/api/v2/avrusskov-test/comments';
+
+export function getComments() {
+ return fetch(host, { method: 'GET' }).then((response) => {
+ return response.json();
+ });
+}
+
+export function getCommentsAuthorazation() {
+ return fetch(host, {
+ method: 'GET',
+ headers: { Authorization: `Bearer ${user.token}` },
+ }).then((response) => {
+ return response.json();
+ });
+}
+
+export function postComment(newComment) {
+ return fetch(host, {
+ method: 'POST',
+ headers: { Authorization: `Bearer ${user.token}` },
+ body: JSON.stringify(newComment),
+ })
+ .then((responce) => {
+ if (responce.status === 201) {
+ return;
+ } else {
+ if (responce.status === 400) {
+ throw new Error('400');
+ }
+ }
+ })
+ .catch((error) => {
+ switch (error.message) {
+ case '400':
+ alert('Имя и комментарий должны быть не короче 3 символов');
+ break;
+ default:
+ alert('Кажется, у вас сломался интернет, попробуйте позже');
+ break;
+ }
+ });
+}
+
+export function updateLike(id) {
+ return fetch(`${host}/${id}/toggle-like`, {
+ method: 'POST',
+ headers: { Authorization: `Bearer ${user.token}` },
+ }).then((response) => {
+ return response.json();
+ });
+}
diff --git a/modules/eventsBtnAddComment.js b/modules/eventsBtnAddComment.js
index ac6a27b..0f06f03 100644
--- a/modules/eventsBtnAddComment.js
+++ b/modules/eventsBtnAddComment.js
@@ -1,23 +1,13 @@
-import { replaceSymbol } from './replace.js';
-import { fetchGetComments } from './fetchGetComments.js';
+import { removeClassError, replaceSymbol } from './helpers.js';
+import { postComment } from './api.js';
+import { renderComments } from './renderComments.js';
-let btnWrite = document.querySelector('.add-form-button');
-let inputName = document.querySelector('.add-form-name');
-let inputText = document.querySelector('.add-form-text');
-const formAddComment = document.querySelector('.add-form');
-const container = document.querySelector('.container');
+async function clickAddComment() {
+ const inputText = document.querySelector('.add-form-text');
+ const formAddComment = document.querySelector('.add-form');
+ const container = document.querySelector('.container');
-function removeClassError(input) {
- input.classList.remove('input-error');
-}
-
-function clickAddComment(API) {
- if (inputName.value === '' || inputText.value === '') {
- if (inputName.value === '') {
- inputName.classList.add('input-error');
-
- setTimeout(() => removeClassError(inputName), 2000);
- }
+ if (inputText.value === '') {
if (inputText.value === '') {
inputText.classList.add('input-error');
@@ -27,63 +17,17 @@ function clickAddComment(API) {
return;
}
- const newComment = {
- text: replaceSymbol(inputText.value),
- name: replaceSymbol(inputName.value),
- forceError: true,
- };
-
formAddComment.style.display = 'none';
const loaderText = document.createElement('p');
loaderText.textContent = 'Комментарий добавляется';
container.appendChild(loaderText);
- let isCrashServer = false;
-
- fetch(API, {
- method: 'POST',
- body: JSON.stringify(newComment),
- })
- .then((responce) => {
- if (responce.status === 201) {
- inputName.value = '';
- inputText.value = '';
-
- return fetchGetComments(API);
- } else {
- if (responce.status === 400) {
- throw new Error('400');
- }
-
- if (responce.status === 500) {
- isCrashServer = true;
- clickAddComment(API);
- }
- }
- })
- .catch((error) => {
- switch (error.message) {
- case '400':
- alert('Имя и комментарий должны быть не короче 3 символов');
- break;
- case '500':
- alert('Сервер сломался, попробуй позже');
- break;
- default:
- alert('Кажется, у вас сломался интернет, попробуйте позже');
- break;
- }
- })
- .finally(() => {
- container.removeChild(loaderText);
-
- if (!isCrashServer) {
- formAddComment.style.display = 'flex';
- }
- });
+ await postComment({ text: replaceSymbol(inputText.value) });
+ renderComments();
}
-export function addClickBtnAddComment(API) {
- btnWrite.addEventListener('click', () => clickAddComment(API));
+export function addClickBtnAddComment() {
+ const btnWrite = document.getElementById('write-button');
+ btnWrite.addEventListener('click', clickAddComment);
}
diff --git a/modules/eventsComment.js b/modules/eventsComment.js
index f6135c9..4c5cc91 100644
--- a/modules/eventsComment.js
+++ b/modules/eventsComment.js
@@ -1,13 +1,7 @@
-import { renderComments } from './render.js';
+import { updateLike } from './api.js';
import { comments } from './comments.js';
-
-function delay(interval = 300) {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve();
- }, interval);
- });
-}
+import { renderComments } from './renderComments.js';
+import { user } from './user.js';
export function addClickBtnLike() {
const arrayBtnLike = document.querySelectorAll('.like-button');
@@ -16,18 +10,18 @@ export function addClickBtnLike() {
btnLike.addEventListener('click', (event) => {
event.stopPropagation();
- btnLike.classList.add('loading-like');
- console.log(btnLike.classList);
+ if (Object.keys(user).length !== 0) {
+ const index = btnLike.dataset.index;
- const index = btnLike.dataset.index;
+ updateLike(comments[index].id).then((data) => {
+ comments[index].likes = data.result.likes;
+ comments[index].isLiked = data.result.isLiked;
- delay(2000).then(() => {
- comments[index].isLiked
- ? comments[index].likes--
- : comments[index].likes++;
- comments[index].isLiked = !comments[index].isLiked;
- renderComments();
- });
+ renderComments();
+ });
+ } else {
+ alert('Нужно авторизоваться');
+ }
});
}
}
diff --git a/modules/fetchGetComments.js b/modules/fetchGetComments.js
deleted file mode 100644
index 8048940..0000000
--- a/modules/fetchGetComments.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { renderComments } from './render.js';
-import { updateComments } from './comments.js';
-
-export function fetchGetComments(API) {
- return fetch(API, { method: 'GET' })
- .then((response) => {
- return response.json();
- })
- .then((data) => {
- updateComments(data.comments);
- renderComments();
- });
-}
diff --git a/modules/replace.js b/modules/helpers.js
similarity index 55%
rename from modules/replace.js
rename to modules/helpers.js
index a91d0e1..de232e5 100644
--- a/modules/replace.js
+++ b/modules/helpers.js
@@ -1,3 +1,7 @@
export function replaceSymbol(text) {
return text.replaceAll('<', '˂').replaceAll('>', '˃');
}
+
+export function removeClassError(input) {
+ input.classList.remove('input-error');
+}
diff --git a/modules/localStorage.js b/modules/localStorage.js
new file mode 100644
index 0000000..05cd72e
--- /dev/null
+++ b/modules/localStorage.js
@@ -0,0 +1,30 @@
+import { updateUser } from './user.js';
+
+export function setLocalStorage(user) {
+ for (let key in user) {
+ localStorage.setItem(key, user[key]);
+ }
+}
+
+export function getLocalStorage() {
+ const newUser = {};
+ newUser['_id'] = localStorage.getItem('_id');
+ newUser['imageUrl'] = localStorage.getItem('imageUrl');
+ newUser['login'] = localStorage.getItem('login');
+ newUser['name'] = localStorage.getItem('name');
+ newUser['password'] = localStorage.getItem('password');
+ newUser['token'] = localStorage.getItem('token');
+
+ return newUser;
+}
+
+export function clearLocalStorage() {
+ localStorage.removeItem('_id');
+ localStorage.removeItem('imageUrl');
+ localStorage.removeItem('login');
+ localStorage.removeItem('name');
+ localStorage.removeItem('password');
+ localStorage.removeItem('token');
+
+ updateUser({});
+}
diff --git a/modules/registration.js b/modules/registration.js
new file mode 100644
index 0000000..1677ecf
--- /dev/null
+++ b/modules/registration.js
@@ -0,0 +1,29 @@
+const hostRegistration = 'https://wedev-api.sky.pro/api/user';
+
+export function Registration(name, login, password) {
+ return fetch(hostRegistration, {
+ method: 'POST',
+ body: JSON.stringify({ name, login, password }),
+ })
+ .then((response) => {
+ if (response.status === 201) {
+ return response.json();
+ } else {
+ if (response.status === 400) {
+ throw new Error('400');
+ } else {
+ throw new Error('Что то пошло не так');
+ }
+ }
+ })
+ .catch((error) => {
+ switch (error.message) {
+ case '400':
+ alert('Пользователь с таким логином уже есть');
+ break;
+ default:
+ alert('Что то пошло не так');
+ break;
+ }
+ });
+}
diff --git a/modules/render.js b/modules/render.js
deleted file mode 100644
index b1d9ae2..0000000
--- a/modules/render.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import { comments } from './comments.js';
-import { addClickBtnLike, addClickComment } from './eventsComment.js';
-import { formatDate } from './date.js';
-
-export function renderComments() {
- const listComment = document.querySelector('.comments');
-
- const htmlComments = comments
- .map((comment, index) => {
- return `
- `;
- })
- .join('');
-
- listComment.innerHTML = htmlComments;
-
- addClickBtnLike();
- addClickComment();
-}
diff --git a/modules/renderComments.js b/modules/renderComments.js
new file mode 100644
index 0000000..d2317e4
--- /dev/null
+++ b/modules/renderComments.js
@@ -0,0 +1,87 @@
+import { comments, updateComments } from './comments.js';
+
+import { renderForm } from './renderForm.js';
+import { renderLogin } from './renderLogin.js';
+import { renderRegistration } from './renderRegistration.js';
+
+import { addClickBtnLike, addClickComment } from './eventsComment.js';
+import { formatDate } from './date.js';
+import { getComments, getCommentsAuthorazation } from './api.js';
+import { renderHeader } from './renderHeader.js';
+import { getLocalStorage } from './localStorage.js';
+import { updateUser } from './user.js';
+
+export async function renderComments() {
+ if (localStorage.getItem('token') !== null) {
+ updateUser(getLocalStorage());
+
+ await getCommentsAuthorazation().then((data) => {
+ updateComments(data.comments);
+ });
+
+ renderHeader();
+ } else {
+ await getComments().then((data) => {
+ updateComments(data.comments);
+ });
+ }
+
+ const app = document.getElementById('app');
+
+ const htmlComments = comments
+ .map((comment, index) => {
+ return `
+ `;
+ })
+ .join('');
+
+ app.innerHTML = `
+
+ `;
+
+ if (localStorage.getItem('token') === null) {
+ const app = document.getElementById('app');
+
+ const login = document.createElement('button');
+ login.classList.add('add-form-button');
+ login.textContent = 'Чтобы добавить комментарий, авторизуйтесь';
+ login.addEventListener('click', () => {
+ renderLogin();
+ });
+
+ const registaration = document.createElement('button');
+ registaration.classList.add('add-form-button');
+ registaration.textContent = 'Регистрация';
+ registaration.addEventListener('click', () => {
+ renderRegistration();
+ });
+
+ app.appendChild(login);
+ app.appendChild(registaration);
+ } else {
+ renderForm();
+ addClickComment();
+ }
+
+ addClickBtnLike();
+}
diff --git a/modules/renderForm.js b/modules/renderForm.js
new file mode 100644
index 0000000..88a15a4
--- /dev/null
+++ b/modules/renderForm.js
@@ -0,0 +1,32 @@
+import { addClickBtnAddComment } from './eventsBtnAddComment.js';
+import { user } from './user.js';
+
+export function renderForm() {
+ const app = document.getElementById('app');
+ const form = document.createElement('div');
+
+ form.innerHTML = `
+
+ `;
+
+ app.appendChild(form);
+
+ addClickBtnAddComment();
+}
diff --git a/modules/renderHeader.js b/modules/renderHeader.js
new file mode 100644
index 0000000..89fa4dd
--- /dev/null
+++ b/modules/renderHeader.js
@@ -0,0 +1,19 @@
+import { clearLocalStorage } from './localStorage.js';
+import { renderComments } from './renderComments.js';
+import { user } from './user.js';
+
+export function renderHeader() {
+ const header = document.getElementById('header');
+
+ header.innerHTML = `
+ ${user.name}
+
+ `;
+
+ const logoutBtn = document.getElementById('logout');
+ logoutBtn.addEventListener('click', () => {
+ clearLocalStorage();
+ header.innerHTML = '';
+ renderComments();
+ });
+}
diff --git a/modules/renderLogin.js b/modules/renderLogin.js
new file mode 100644
index 0000000..b6e161b
--- /dev/null
+++ b/modules/renderLogin.js
@@ -0,0 +1,63 @@
+import { removeClassError } from './helpers.js';
+import { setLocalStorage } from './localStorage.js';
+import { Login } from './login.js';
+import { renderComments } from './renderComments.js';
+import { updateUser } from './user.js';
+
+export function renderLogin() {
+ window.scrollTo(0, 0);
+
+ const app = document.getElementById('app');
+
+ app.innerHTML = `
+ `;
+
+ const loginInput = document.getElementById('login-input');
+ const passwordInput = document.getElementById('password-input');
+ const loginBtn = document.getElementById('login-btn');
+ const backBtn = document.getElementById('back-btn');
+
+ loginBtn.addEventListener('click', () => {
+ if (loginInput.value === '' || passwordInput.value === '') {
+ if (loginInput.value === '') {
+ loginInput.classList.add('input-error');
+
+ setTimeout(() => removeClassError(loginInput), 2000);
+ }
+
+ if (passwordInput.value === '') {
+ passwordInput.classList.add('input-error');
+
+ setTimeout(() => removeClassError(passwordInput), 2000);
+ }
+
+ return;
+ }
+ Login(loginInput.value, passwordInput.value).then((data) => {
+ setLocalStorage(data.user);
+ updateUser(data.user);
+ renderComments();
+ });
+ });
+
+ backBtn.addEventListener('click', () => {
+ renderComments();
+ });
+}
diff --git a/modules/renderRegistration.js b/modules/renderRegistration.js
new file mode 100644
index 0000000..b94599d
--- /dev/null
+++ b/modules/renderRegistration.js
@@ -0,0 +1,84 @@
+import { removeClassError } from './helpers.js';
+import { setLocalStorage } from './localStorage.js';
+import { Registration } from './registration.js';
+import { renderComments } from './renderComments.js';
+import { updateUser } from './user.js';
+
+export function renderRegistration() {
+ window.scrollTo(0, 0);
+
+ const app = document.getElementById('app');
+
+ app.innerHTML = `
+ `;
+
+ const nameInput = document.getElementById('name-input');
+ const loginInput = document.getElementById('login-input');
+ const passwordInput = document.getElementById('password-input');
+ const registrationBtn = document.getElementById('registration-btn');
+ const backBtn = document.getElementById('back-btn');
+
+ registrationBtn.addEventListener('click', () => {
+ if (
+ loginInput.value === '' ||
+ passwordInput.value === '' ||
+ nameInput.value === ''
+ ) {
+ if (nameInput.value === '') {
+ nameInput.classList.add('input-error');
+
+ setTimeout(() => removeClassError(nameInput), 2000);
+ }
+ if (loginInput.value === '') {
+ loginInput.classList.add('input-error');
+
+ setTimeout(() => removeClassError(loginInput), 2000);
+ }
+
+ if (passwordInput.value === '') {
+ passwordInput.classList.add('input-error');
+
+ setTimeout(() => removeClassError(passwordInput), 2000);
+ }
+
+ return;
+ }
+
+ Registration(
+ nameInput.value,
+ loginInput.value,
+ passwordInput.value,
+ ).then((data) => {
+ setLocalStorage(data.user);
+ updateUser(data.user);
+ renderComments();
+ });
+ });
+
+ backBtn.addEventListener('click', () => {
+ renderComments();
+ });
+}
diff --git a/modules/user.js b/modules/user.js
new file mode 100644
index 0000000..1ba4d6c
--- /dev/null
+++ b/modules/user.js
@@ -0,0 +1,5 @@
+export let user = {};
+
+export function updateUser(newUser) {
+ user = newUser;
+}
diff --git a/styles.css b/styles.css
index 21d5e6a..f8f03fe 100644
--- a/styles.css
+++ b/styles.css
@@ -2,21 +2,6 @@ body {
margin: 0;
}
-@keyframes rotating {
- from {
- transform: rotate(0deg);
- }
- 25% {
- transform: rotate(30deg);
- }
- 75% {
- transform: rotate(-30deg);
- }
- to {
- transform: rotate(0deg);
- }
-}
-
.container {
font-family: Helvetica;
color: #ffffff;
@@ -29,6 +14,25 @@ body {
min-height: 100vh;
}
+.header {
+ font-family: Helvetica;
+ color: #ffffff;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+ gap: 30px;
+ background: #202020;
+}
+
+.header-btn {
+ font-size: 24px;
+ padding: 10px 20px;
+ background-color: #bcec30;
+ border: none;
+ border-radius: 18px;
+ cursor: pointer;
+}
+
.comments,
.comment {
margin: 0;
@@ -106,10 +110,6 @@ body {
background-image: url("data:image/svg+xml,%3Csvg width='22' height='20' viewBox='0 0 22 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15.95 0C14.036 0 12.199 0.882834 11 2.26703C9.801 0.882834 7.964 0 6.05 0C2.662 0 0 2.6267 0 5.99455C0 10.1035 3.74 13.4714 9.405 18.5613L11 20L12.595 18.5613C18.26 13.4714 22 10.1035 22 5.99455C22 2.6267 19.338 0 15.95 0Z' fill='%23BCEC30'/%3E%3C/svg%3E");
}
-.loading-like {
- animation: rotating 2s linear infinite;
-}
-
.add-form {
padding: 20px;
margin-top: 48px;
@@ -134,6 +134,20 @@ body {
padding: 11px 22px;
}
+.add-form-name_login,
+.add-form-text {
+ font-size: 16px;
+ font-family: Helvetica;
+ border-radius: 8px;
+ border: none;
+}
+
+.add-form-name_login {
+ width: 300px;
+ padding: 11px 22px;
+ margin-top: 12px;
+}
+
.add-form-text {
margin-top: 12px;
padding: 22px;
@@ -145,6 +159,12 @@ body {
justify-content: flex-end;
}
+.add-form-login {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
+
.add-form-button {
margin-top: 24px;
font-size: 24px;
Загрузка
- -