diff --git a/api.js b/api.js
index 123a9e3b6..5733fc2f5 100644
--- a/api.js
+++ b/api.js
@@ -4,6 +4,24 @@ const personalKey = "prod";
const baseHost = "https://webdev-hw-api.vercel.app";
const postsHost = `${baseHost}/api/v1/${personalKey}/instapro`;
+export async function addNewPost({ token, description, imageUrl }) {
+ return fetch(postsHost, {
+ method: "POST",
+ headers: {
+ Authorization: token,
+ },
+ body: JSON.stringify({
+ description,
+ imageUrl,
+ }),
+ }).then((response) => {
+ if (response.status === 400) {
+ throw new Error("Не удалось добавить пост");
+ }
+ return response.json();
+ });
+}
+
export function getPosts({ token }) {
return fetch(postsHost, {
method: "GET",
@@ -23,7 +41,7 @@ export function getPosts({ token }) {
});
}
-export function registerUser({ login, password, name, imageUrl }) {
+export async function registerUser({ login, password, name, imageUrl }) {
return fetch(baseHost + "/api/user", {
method: "POST",
body: JSON.stringify({
@@ -67,3 +85,50 @@ export function uploadImage({ file }) {
return response.json();
});
}
+
+export async function getUserPosts({ token, id }) {
+ const response = await fetch(postsHost + "/user-posts/" + id, {
+ method: "GET",
+ headers: {
+ Authorization: token,
+ },
+ });
+ if (!response.ok) {
+ throw new Error("Ошибка запроса");
+ }
+ return await response.json();
+} //Сетевой запрос постов пользователя
+
+export async function setLike({ token, id }) {
+ try {
+ const response = await fetch(postsHost + `/${id}/like`, {
+ method: "POST",
+ headers: {
+ Authorization: token,
+ },
+ });
+ if (!response.ok) {
+ throw new Error("сетевая ошибка");
+ }
+ return await response.json();
+ } catch (error) {
+ console.log(error);
+ }
+}
+
+export async function unsetLike({ token, id }) {
+ try {
+ const response = await fetch(postsHost + `/${id}/dislike`, {
+ method: "POST",
+ headers: {
+ Authorization: token,
+ },
+ });
+ if (!response.ok) {
+ throw new Error("сетевая ошибка");
+ }
+ return await response.json();
+ } catch (error) {
+ console.log(error);
+ }
+}
diff --git a/components/add-post-page-component.js b/components/add-post-page-component.js
index 8277f093b..2fdd02ecf 100644
--- a/components/add-post-page-component.js
+++ b/components/add-post-page-component.js
@@ -1,23 +1,47 @@
+import { renderHeaderComponent } from "./header-component.js";
+import { renderUploadImageComponent } from './upload-image-component.js'
export function renderAddPostPageComponent({ appEl, onAddPostClick }) {
+
const render = () => {
// @TODO: Реализовать страницу добавления поста
- const appHtml = `
+ let appHtml = `
-
- Cтраница добавления поста
-
-
+
+
+
`;
-
+ let imageUrl = '';
appEl.innerHTML = appHtml;
-
+ renderHeaderComponent({element: document.querySelector('.header-container')})
+ renderUploadImageComponent({element: document.querySelector('.upload-image-container'),
+ onImageUrlChange:(url)=> imageUrl = url})
+ let textAreaElement = document.getElementById('post-description')
+
document.getElementById("add-button").addEventListener("click", () => {
+ if (!textAreaElement.value || !imageUrl){
+ alert ('Заполните все поля')
+ return
+ }
+
onAddPostClick({
- description: "Описание картинки",
- imageUrl: "https://image.png",
+ description: textAreaElement.value,
+ imageUrl: imageUrl,
});
+
});
};
render();
+
}
diff --git a/components/loading-page-component.js b/components/loading-page-component.js
index c93522573..3baea5203 100644
--- a/components/loading-page-component.js
+++ b/components/loading-page-component.js
@@ -9,7 +9,7 @@ import { renderHeaderComponent } from "./header-component.js";
* @param {Object} params.user - Объект пользователя, содержащий данные о текущем авторизованном пользователе (если он есть).
* @param {Function} params.goToPage - Функция для навигации по страницам.
*/
-export function renderLoadingPageComponent({ appEl, user, goToPage }) {
+export function renderLoadingPageComponent({ appEl }) {
/**
* HTML-разметка страницы загрузки.
* Содержит контейнер заголовка и индикатор загрузки.
@@ -30,8 +30,6 @@ export function renderLoadingPageComponent({ appEl, user, goToPage }) {
* Передаются данные пользователя и функция навигации.
*/
renderHeaderComponent({
- user,
- element: document.querySelector(".header-container"),
- goToPage,
+ element: document.querySelector(".header-container")
});
}
diff --git a/components/posts-page-component.js b/components/posts-page-component.js
index 662ccdbdc..44c502be8 100644
--- a/components/posts-page-component.js
+++ b/components/posts-page-component.js
@@ -1,6 +1,10 @@
import { USER_POSTS_PAGE } from "../routes.js";
import { renderHeaderComponent } from "./header-component.js";
-import { posts, goToPage } from "../index.js";
+import { posts, goToPage, getToken } from "../index.js";
+
+import { formatDistanceToNow } from "https://cdn.skypack.dev/date-fns";
+import { ru } from "https://cdn.skypack.dev/date-fns/locale";
+import { toggleLike } from "../helpers.js";
export function renderPostsPageComponent({ appEl }) {
// @TODO: реализовать рендер постов из api
@@ -14,84 +18,57 @@ export function renderPostsPageComponent({ appEl }) {
- -
-
-
-

-
-
-
-
- Нравится: 2
-
-
-
- Иван Иваныч
- Ромашка, ромашка...
-
-
- 19 минут назад
-
-
- -
-
-
-
-
-

-
-
-
-
- Нравится: 35
-
-
-
- Варварва Н.
- Нарисовала картину, посмотрите какая красивая
-
-
- 3 часа назад
-
-
- -
- `;
+
`
+ )
+ .join("")}
+
+
`;
appEl.innerHTML = appHtml;
@@ -106,4 +83,6 @@ export function renderPostsPageComponent({ appEl }) {
});
});
}
+ toggleLike()
}
+
diff --git a/components/user-post-page-component.js b/components/user-post-page-component.js
new file mode 100644
index 000000000..c7e3d1180
--- /dev/null
+++ b/components/user-post-page-component.js
@@ -0,0 +1,74 @@
+import { posts } from "../index.js";
+import { formatDistanceToNow } from "https://cdn.skypack.dev/date-fns";
+import { ru } from "https://cdn.skypack.dev/date-fns/locale";
+import { renderHeaderComponent } from "./header-component.js";
+import { toggleLike } from "../helpers.js";
+
+export function renderUserPostsPageComponent({ appEl }) {
+ let userPosts = posts.posts;
+
+ console.log(userPosts);
+ const appHtml =
+ `
+
+
+
+ ${userPosts.map((post) => (
+ `-
+
+
+

+
+
+
+
+ Нравится: ${
+ post.likes.length
+ ? post.likes.length > 1
+ ? `${
+ post.likes[
+ Math.floor(
+ Math.random() * post.likes.length
+ )
+ ].name
+ } и еще ${post.likes.length - 1}`
+ : post.likes[0].name
+ : "0"
+ }
+
+
+
+ ${post.user.name}
+ ${post.description}
+
+
+ ${formatDistanceToNow(post.createdAt, {
+ locale: ru,
+ })} назад
+
+ `
+ )
+
+
+).join('')}
+
+
`
+
+ appEl.innerHTML = appHtml;
+ renderHeaderComponent({
+ element: document.querySelector(".header-container"),
+ }
+ );
+ toggleLike();
+}
diff --git a/helpers.js b/helpers.js
index b47d3b777..95c52446c 100644
--- a/helpers.js
+++ b/helpers.js
@@ -1,15 +1,55 @@
+import { setLike, unsetLike } from "../api.js";
+import { posts, getToken } from "../index.js";
+
export function saveUserToLocalStorage(user) {
window.localStorage.setItem("user", JSON.stringify(user));
}
-export function getUserFromLocalStorage(user) {
+export function getUserFromLocalStorage() {
try {
return JSON.parse(window.localStorage.getItem("user"));
} catch (error) {
return null;
}
-}
+};
export function removeUserFromLocalStorage(user) {
window.localStorage.removeItem("user");
+};
+
+export function toggleLike(){
+ for (let buttonLike of document.querySelectorAll(".like-button")) {
+ buttonLike.addEventListener("click", async (event) => {
+ if (!getUserFromLocalStorage()){
+ alert('Сначала авторизуйтесь')
+ return
+ }
+ const postId = event.target.dataset.postId;
+ const post = posts.find((post) => post.id === postId);
+ const postLikes = event.target.closest(".post-likes");
+ const isLiked = !post.isLiked;
+ const likeImageElement = postLikes.querySelector("img");
+ const postLikeTextElement = postLikes.querySelector(".post-likes-text");
+
+ likeImageElement.src = isLiked
+ ? "./assets/images/like-active.svg"
+ : "./assets/images/like-not-active.svg";
+ let response;
+ if (post.isLiked) {
+ response = await unsetLike({ token: getToken(), id: postId });
+ } else {
+ response = await setLike({ token: getToken(), id: postId });
+ }
+ post.likes = response.post.likes;
+ post.isLiked = response.post.isLiked;
+ postLikeTextElement.innerHTML = ` Нравится: ${
+ post.likes.length
+ ? post.likes.length > 1
+ ? `${ post.likes[Math.floor(Math.random() * post.likes.length)].name } и еще ${post.likes.length - 1}`
+ : post.likes[0].name
+ : "0"
+ }`;
+ console.log(post.likes, post.isLiked,post);
+ });
+ }
}
diff --git a/index.js b/index.js
index 7f1817c75..60d4ccd48 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,4 @@
-import { getPosts } from "./api.js";
+import { getPosts, addNewPost, getUserPosts } from "./api.js";
import { renderAddPostPageComponent } from "./components/add-post-page-component.js";
import { renderAuthPageComponent } from "./components/auth-page-component.js";
import {
@@ -15,12 +15,13 @@ import {
removeUserFromLocalStorage,
saveUserToLocalStorage,
} from "./helpers.js";
+import { renderUserPostsPageComponent } from "./components/user-post-page-component.js";
export let user = getUserFromLocalStorage();
export let page = null;
export let posts = [];
-const getToken = () => {
+export const getToken = () => {
const token = user ? `Bearer ${user.token}` : undefined;
return token;
};
@@ -34,6 +35,13 @@ export const logout = () => {
/**
* Включает страницу приложения
*/
+
+export const updatePosts = (newPosts) => {
+ posts = newPosts
+}
+
+
+
export const goToPage = (newPage, data) => {
if (
[
@@ -67,11 +75,20 @@ export const goToPage = (newPage, data) => {
}
if (newPage === USER_POSTS_PAGE) {
+ page = LOADING_PAGE;
+ renderApp();
// @@TODO: реализовать получение постов юзера из API
console.log("Открываю страницу пользователя: ", data.userId);
- page = USER_POSTS_PAGE;
- posts = [];
- return renderApp();
+ return getUserPosts({token: getToken(),id: data.userId})
+ .then ((userPosts)=>{
+ posts = userPosts;
+ page = USER_POSTS_PAGE;
+ renderApp();
+ }
+ ).catch((error)=>{
+ console.log(error);
+ goToPage(POSTS_PAGE)
+ })
}
page = newPage;
@@ -110,11 +127,13 @@ const renderApp = () => {
return renderAddPostPageComponent({
appEl,
onAddPostClick({ description, imageUrl }) {
+ addNewPost({ token:getToken(), description, imageUrl})
// @TODO: реализовать добавление поста в API
console.log("Добавляю пост...", { description, imageUrl });
goToPage(POSTS_PAGE);
},
- });
+ })
+
}
if (page === POSTS_PAGE) {
@@ -125,8 +144,8 @@ const renderApp = () => {
if (page === USER_POSTS_PAGE) {
// @TODO: реализовать страницу с фотографиями отдельного пользвателя
- appEl.innerHTML = "Здесь будет страница фотографий пользователя";
- return;
+
+ return renderUserPostsPageComponent({appEl});
}
};