From 0a0be8409cf21c8f4ede5fa90c8041abc5caca34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D1=81=D1=8C=20=D0=B2=D0=B0=D1=88=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BC=D1=8F?= <здесь ваша почта> Date: Wed, 10 Apr 2024 18:51:57 +0700 Subject: [PATCH 01/17] =?UTF-8?q?=D0=B8=D0=BD=D1=82=D0=B5=D0=B3=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B0=D0=BF=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api.js | 42 +++++++++++++++ components/auth-page-component.js | 23 ++++---- components/posts-page-component.js | 86 ++++++++---------------------- index.js | 72 ++++++++++++++++++------- 4 files changed, 126 insertions(+), 97 deletions(-) diff --git a/api.js b/api.js index 8997c44d..17f65721 100644 --- a/api.js +++ b/api.js @@ -68,3 +68,45 @@ export function uploadImage({ file }) { return response.json(); }); } +//посты пользователя +export function fetchPostsUser( id , { token }) { + return fetch(`${postsHost}/user-posts/${id}`, { + method: "GET", + headers: { + Authorization: token, + }, + }) + .then((response) => { + if (response.status === 401) { + throw new Error("Нет авторизации"); + } + + return response.json(); + }) + .then((data) => { + return data.posts; + }); +} +//новый пост +export const userPosts = ({ token, description, imageUrl }) => { + return fetch(postsHost, { + method: "POST", + body: JSON.stringify({ + description, + imageUrl, + }), + headers: { + Authorization: token, + } + }) + .then((response) => { + if (response.status === 500) { + throw new Error("Сервер упал"); + } else if (response.status === 400) { + throw new Error("Плохой запрос"); + } else { + return response.json(); + } + }) + +} \ No newline at end of file diff --git a/components/auth-page-component.js b/components/auth-page-component.js index cf66a3ae..c41c554d 100644 --- a/components/auth-page-component.js +++ b/components/auth-page-component.js @@ -12,31 +12,28 @@ export function renderAuthPageComponent({ appEl, setUser }) {
- Нравится: 2 + Нравится: + ${post.likes.length === 0 ? 0 : post.likes.length === 1 ? post.likes[0].name : post.likes[(post.likes.length - 1)].name + ' и еще ' + (post.likes.length - 1)} +
@@ -67,35 +69,44 @@ export function renderPostsPageComponent({ appEl }) { } function getLikePost() { - const likesButton = document.querySelectorAll('.like-button'); - for (const like of likesButton) { - like.addEventListener("click", (event) => { + const likesButtons = document.querySelectorAll('.like-button'); + + likesButtons.forEach((button) => { + button.addEventListener("click", (event) => { event.stopPropagation(); - const id = like.dataset.id; - const liked = like.dataset.liked; + + const id = button.dataset.postId; // Получаем id поста + const isLiked = button.dataset.liked; // Узнаем поставил ли пользователь лайк + const index = posts.findIndex((post) => post.id === id); // Находим индекс поста в массиве posts console.log(id); - console.log(liked); - if (liked === 'false') { - getLike(id, { token: getToken() }) + console.log(isLiked); + console.log(index); + if (index === -1) { + console.error("Ошибка: пост не найден"); + return; + } + + if (isLiked === 'false') { + getLike({ id, token: getToken() }) .then(() => { - like.querySelector("img").src = './assets/images/like-active.svg'; - like.dataset.liked = "true"; + + goToPage(POSTS_PAGE); }) .catch((error) => { console.error("Ошибка при добавлении лайка:", error); }); } else { - getDislike(id, { token: getToken() }) + getDislike({ id, token: getToken() }) .then(() => { - like.querySelector("img").src = './assets/images/like-not-active.svg'; - like.dataset.liked = "false"; + + goToPage(POSTS_PAGE); }) .catch((error) => { console.error("Ошибка при удалении лайка:", error); }); } }); - } + }); } getLikePost(); From 718c4b761600f282e936dfeb3e1fa9dfb521cd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D1=81=D1=8C=20=D0=B2=D0=B0=D1=88=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BC=D1=8F?= <здесь ваша почта> Date: Sat, 13 Apr 2024 09:58:17 +0700 Subject: [PATCH 08/17] =?UTF-8?q?=D1=87=D1=82=D0=BE-=D1=82=D0=BE=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D0=BC=D0=B5=D0=BB=D0=BE=D1=87=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api.js | 8 ++++---- components/posts-page-component.js | 10 +++++----- index.js | 15 +-------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/api.js b/api.js index 2341460a..10be8c27 100644 --- a/api.js +++ b/api.js @@ -111,8 +111,8 @@ export const userPosts = ({ token, description, imageUrl }) => { } //лайки -export const getLike = ({ postId, token }) => { - return fetch(`${postsHost}/${postId}/like`, { +export const getLike = (id, { token }) => { + return fetch(`${postsHost}/${id}/like`, { method: "POST", headers: { Authorization: token, @@ -131,8 +131,8 @@ export const getLike = ({ postId, token }) => { }; -export const getDislike = ({ postId, token }) => { - return fetch(`${postsHost}/${postId}/dislike`, { +export const getDislike = (id, { token }) => { + return fetch(`${postsHost}/${id}/dislike`, { method: "POST", headers: { Authorization: token, diff --git a/components/posts-page-component.js b/components/posts-page-component.js index dee8f073..d876fc99 100644 --- a/components/posts-page-component.js +++ b/components/posts-page-component.js @@ -1,4 +1,4 @@ -import { USER_POSTS_PAGE } from "../routes.js"; +import { POSTS_PAGE, USER_POSTS_PAGE } from "../routes.js"; import { renderHeaderComponent } from "./header-component.js"; import { posts, goToPage, getToken } from "../index.js"; import { getDislike, getLike } from "../api.js"; @@ -87,8 +87,8 @@ export function renderPostsPageComponent({ appEl }) { } if (isLiked === 'false') { - getLike({ id, token: getToken() }) - .then(() => { + getLike(id, { token: getToken() }) + .then((updatedPost) => { goToPage(POSTS_PAGE); }) @@ -96,8 +96,8 @@ export function renderPostsPageComponent({ appEl }) { console.error("Ошибка при добавлении лайка:", error); }); } else { - getDislike({ id, token: getToken() }) - .then(() => { + getDislike(id, { token: getToken() }) + .then((updatedPost) => { goToPage(POSTS_PAGE); }) diff --git a/index.js b/index.js index 9cc102c2..c6752bf1 100644 --- a/index.js +++ b/index.js @@ -69,27 +69,14 @@ export const goToPage = (newPage, data) => { else if (newPage === POSTS_PAGE) { page = LOADING_PAGE; - renderApp(); - return getAPI(); - - // getPosts({ token: getToken() }) - // .then((newPosts) => { - // page = POSTS_PAGE; - // posts = newPosts; - // renderApp(); - // }) - // .catch((error) => { - // console.error(error); - // goToPage(POSTS_PAGE); - // }); } else if (newPage === USER_POSTS_PAGE) { // TODO: реализовать получение постов юзера из API console.log("Открываю страницу пользователя: ", data.userId); page = LOADING_PAGE; - renderApp(); + renderApp(); return fetchPostsUser(data.userId, { token: getToken() }) .then((newPosts) => { From 4b0e9793514c5642d183d02e34325a35aa5bb3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D1=81=D1=8C=20=D0=B2=D0=B0=D1=88=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BC=D1=8F?= <здесь ваша почта> Date: Sat, 13 Apr 2024 10:44:43 +0700 Subject: [PATCH 09/17] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=87=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BB=D0=B0=D0=B9=D0=BA=D0=B8,=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=20=D0=BF=D0=B5=D1=80=D1=81?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api.js | 3 ++- components/posts-page-component.js | 17 +++++++++-------- index.js | 15 +++++++++++++-- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/api.js b/api.js index 10be8c27..00a5decf 100644 --- a/api.js +++ b/api.js @@ -1,6 +1,6 @@ // Замени на свой, чтобы получить независимый от других набор данных. // "боевая" версия инстапро лежит в ключе prod -const personalKey = "prod"; +const personalKey = "alenka-s"; const baseHost = "https://webdev-hw-api.vercel.app"; const postsHost = `${baseHost}/api/v1/${personalKey}/instapro`; @@ -125,6 +125,7 @@ export const getLike = (id, { token }) => { return response.json(); }) .catch((error) => { + alert('Вы не авторизованы!') console.error("Ошибка при установке лайка:", error); throw error; }); diff --git a/components/posts-page-component.js b/components/posts-page-component.js index d876fc99..1c4fe064 100644 --- a/components/posts-page-component.js +++ b/components/posts-page-component.js @@ -3,7 +3,7 @@ import { renderHeaderComponent } from "./header-component.js"; import { posts, goToPage, getToken } from "../index.js"; import { getDislike, getLike } from "../api.js"; -export function renderPostsPageComponent({ appEl }) { +export function renderPostsPageComponent({ appEl, userView }) { // TODO: реализовать рендер постов из api console.log("Актуальный список постов:", posts); @@ -75,9 +75,9 @@ export function renderPostsPageComponent({ appEl }) { button.addEventListener("click", (event) => { event.stopPropagation(); - const id = button.dataset.postId; // Получаем id поста - const isLiked = button.dataset.liked; // Узнаем поставил ли пользователь лайк - const index = posts.findIndex((post) => post.id === id); // Находим индекс поста в массиве posts + const id = button.dataset.postId; + const isLiked = button.dataset.liked; + const index = posts.findIndex((post) => post.id === id); console.log(id); console.log(isLiked); console.log(index); @@ -89,8 +89,9 @@ export function renderPostsPageComponent({ appEl }) { if (isLiked === 'false') { getLike(id, { token: getToken() }) .then((updatedPost) => { - - goToPage(POSTS_PAGE); + const newPage = userView ? USER_POSTS_PAGE : POSTS_PAGE; + goToPage(newPage, { userId: posts[0].user.id }); + // goToPage(POSTS_PAGE); }) .catch((error) => { console.error("Ошибка при добавлении лайка:", error); @@ -98,8 +99,8 @@ export function renderPostsPageComponent({ appEl }) { } else { getDislike(id, { token: getToken() }) .then((updatedPost) => { - - goToPage(POSTS_PAGE); + const newPage = userView ? USER_POSTS_PAGE : POSTS_PAGE; + goToPage(newPage, { userId: posts[0].user.id }); }) .catch((error) => { console.error("Ошибка при удалении лайка:", error); diff --git a/index.js b/index.js index c6752bf1..6aa93d36 100644 --- a/index.js +++ b/index.js @@ -42,7 +42,9 @@ function getAPI() { posts = newPosts; renderApp(); } else { + goToPage(ADD_POSTS_PAGE); console.log("Нет постов"); + } }) .catch((error) => { @@ -132,13 +134,22 @@ const renderApp = () => { .then(() => { goToPage(POSTS_PAGE); }) + .catch((error) => { + if (error.message === "Сервер упал") { + alert("Сервер сломался, попробуйте позже"); + postPosts({ token: getToken(), description, imageUrl }); + } else { + alert('Кажется, у вас не работает интернет, попробуйте позже'); + console.log(error); + } + }); }, }); } if (page === POSTS_PAGE) { return renderPostsPageComponent({ - appEl, + appEl, userView: false, }); } @@ -146,7 +157,7 @@ const renderApp = () => { // TODO: реализовать страницу фотографию пользвателя appEl.innerHTML = "Здесь будет страница фотографий пользователя"; return renderPostsPageComponent({ - appEl, + appEl, userView: true, }); } }; From 9fa13f4a2234108928b9d57089daff7ea395f881 Mon Sep 17 00:00:00 2001 From: Alena-Sartakova <153823374+Alena-Sartakova@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:16:06 +0700 Subject: [PATCH 10/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 216dfc2a..2cc39d7e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ MVP аналога популярной соц. сети для обмена ф ## Ссылка на приложение: -https:: +https://alena-sartakova.github.io/ ## Первоначальная оценка From 39a69be2f1f0f5dcb8a587ee885429fc04f57378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D1=81=D1=8C=20=D0=B2=D0=B0=D1=88=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BC=D1=8F?= <здесь ваша почта> Date: Sat, 13 Apr 2024 11:17:18 +0700 Subject: [PATCH 11/17] =?UTF-8?q?=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=81=D0=B0=D0=B9=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 216dfc2a..f90aed1c 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ MVP аналога популярной соц. сети для обмена ф ## Ссылка на приложение: -https:: +https://alena-sartakova.github.io/ ## Первоначальная оценка -ХХХХ часов +35 часов ## Фактически затраченное время -YYYY часов +30 часов From 6d224888e886e3ce6508522d2928a28374f5a037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D1=81=D1=8C=20=D0=B2=D0=B0=D1=88=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BC=D1=8F?= <здесь ваша почта> Date: Sun, 14 Apr 2024 15:43:13 +0700 Subject: [PATCH 12/17] sanitize, li --- api.js | 18 ++++++++++-------- index.js | 3 ++- styles.css | 4 ++++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/api.js b/api.js index 00a5decf..cdef812c 100644 --- a/api.js +++ b/api.js @@ -1,4 +1,7 @@ // Замени на свой, чтобы получить независимый от других набор данных. + +import { sanitizeHtml } from "./helpers.js"; + // "боевая" версия инстапро лежит в ключе prod const personalKey = "alenka-s"; const baseHost = "https://webdev-hw-api.vercel.app"; @@ -28,9 +31,9 @@ export function registerUser({ login, password, name, imageUrl }) { return fetch(baseHost + "/api/user", { method: "POST", body: JSON.stringify({ - login, - password, - name, + login: sanitizeHtml(login), + password: sanitizeHtml(password), + name: sanitizeHtml(name), imageUrl, }), }).then((response) => { @@ -91,7 +94,7 @@ export const userPosts = ({ token, description, imageUrl }) => { return fetch(postsHost, { method: "POST", body: JSON.stringify({ - description, + description: sanitizeHtml(description), imageUrl, }), headers: { @@ -119,14 +122,13 @@ export const getLike = (id, { token }) => { } }) .then((response) => { - if (!response.ok) { - throw new Error(`Ошибка ${response.status}: ${response.statusText}`); + if (response.ok) { + return response.json(); } - return response.json(); + throw new Error(`Нет авторизации`); }) .catch((error) => { alert('Вы не авторизованы!') - console.error("Ошибка при установке лайка:", error); throw error; }); diff --git a/index.js b/index.js index 6aa93d36..482159f1 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,7 @@ import { renderLoadingPageComponent } from "./components/loading-page-component. import { getUserFromLocalStorage, removeUserFromLocalStorage, + sanitizeHtml, saveUserToLocalStorage, } from "./helpers.js"; @@ -130,7 +131,7 @@ const renderApp = () => { onAddPostClick({ description, imageUrl }) { // TODO: реализовать добавление поста в API console.log("Добавляю пост...", { description, imageUrl }); - userPosts({ token: getToken(), description, imageUrl }) + userPosts({ token: getToken(), description: sanitizeHtml(description), imageUrl }) .then(() => { goToPage(POSTS_PAGE); }) diff --git a/styles.css b/styles.css index 57bc08b1..de35d924 100644 --- a/styles.css +++ b/styles.css @@ -196,3 +196,7 @@ width: 100%; text-align: center; } + +li { + list-style-type: none; +} \ No newline at end of file From dd4edad56365d26e6e4bf7361b3d3c183a268c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D1=81=D1=8C=20=D0=B2=D0=B0=D1=88=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BC=D1=8F?= <здесь ваша почта> Date: Sun, 14 Apr 2024 16:46:01 +0700 Subject: [PATCH 13/17] =?UTF-8?q?=D0=94=D0=B0=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/posts-page-component.js | 13 +- dist/index.js | 526 +++++++++++ index.html | 26 +- package-lock.json | 1373 ++++++++++++++++++++++++++++ package.json | 19 + webpack.config.js | 7 + 6 files changed, 1946 insertions(+), 18 deletions(-) create mode 100644 dist/index.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 webpack.config.js diff --git a/components/posts-page-component.js b/components/posts-page-component.js index 1c4fe064..ac146255 100644 --- a/components/posts-page-component.js +++ b/components/posts-page-component.js @@ -2,7 +2,7 @@ import { POSTS_PAGE, USER_POSTS_PAGE } from "../routes.js"; import { renderHeaderComponent } from "./header-component.js"; import { posts, goToPage, getToken } from "../index.js"; import { getDislike, getLike } from "../api.js"; - +import { format } from "date-fns"; export function renderPostsPageComponent({ appEl, userView }) { // TODO: реализовать рендер постов из api console.log("Актуальный список постов:", posts); @@ -13,6 +13,7 @@ export function renderPostsPageComponent({ appEl, userView }) { */ let postsHtml = posts.map((post) => { + const createDate = format(new Date(), 'yyyy-MM-dd '); return `
- 19 минут назад -
+${post.user.name}
\r\n\r\n Нравится: \r\n ${post.likes.length === 0 ? 0 : post.likes.length === 1 ? post.likes[0].name : post.likes[(post.likes.length - 1)].name + ' и еще ' + (post.likes.length - 1)}\r\n \r\n
\r\n\r\n ${post.user.name}\r\n ${post.description}\r\n
\r\n