Skip to content
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
122 changes: 119 additions & 3 deletions api.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { getToken, user, posts } from "./index.js";
import { renderPostsPageComponent } from "./components/posts-page-component.js";

// Замени на свой, чтобы получить независимый от других набор данных.
// "боевая" версия инстапро лежит в ключе prod
const personalKey = "prod";
const personalKey = "tatiana-alekseeva";
const baseHost = "https://webdev-hw-api.vercel.app";
const postsHost = `${baseHost}/api/v1/${personalKey}/instapro`;
const postsHost = `https://wedev-api.sky.pro/api/v1/:${personalKey}/instapro`;

export function getPosts({ token }) {
return fetch(postsHost, {
Expand All @@ -19,10 +22,123 @@ export function getPosts({ token }) {
return response.json();
})
.then((data) => {
return data.posts;
const appPosts = data.posts.map((post) => {
return {
id: post.id,
imageUrl: post.imageUrl,
createdAt: post.createdAt,
description: post.description,
userId: post.user.id,
userName: post.user.name,
userLogin: post.user.login,
userImg: post.user.imageUrl,
likes: post.likes || [],
isLiked: post.isLiked,
};
});

return appPosts;
});
}

export function fetchUserPosts(userId) {
return fetch(postsHost + `/user-posts/${userId}`)
.then((response) => {
return response.json();
})
.then((data) => {
const appPosts = data.posts.map((post) => {
return {
id: post.id,
imageUrl: post.imageUrl,
createdAt: post.createdAt,
description: post.description,
userId: post.user.id,
userName: post.user.name,
userLogin: post.user.login,
userImg: post.user.imageUrl,
likes: post.likes || [],
isLiked: post.isLiked,
};
});

return appPosts;
});
}

export function fetchLikePosts(postId, isLiked) {
if (!user || !user._id || !user.name) {
throw new Error("Пользователь не авторизован");
}

const userId = user._id;
const userName = user.name;
const method = isLiked ? "dislike" : "like";
console.log(user._id);
console.log(user.name);

return fetch(`${postsHost}/${postId}/${method}`, {
method: "POST",
headers: {
Authorization: getToken(),
},
body: JSON.stringify({
postId,
isLiked,
userId,
userName,
}),
})
.then((response) => {
if (!response.ok) {
throw new Error("Ошибка при обработке лайка");
}

console.log(response);
return response.json();
})
.then((data) => {
const index = posts.findIndex((p) => p.id === postId);
if (index !== -1) {
posts[index] = {
...posts[index],
isLiked: !posts[index].isLiked,
likes: data.post.likes,
};
}
console.log(data);
})
.catch((error) => {
console.error("Ошибка:", error);
});
}

export function onAddPostClick(description, imageUrl) {
return fetch(postsHost, {
method: "POST",
headers: {
Authorization: getToken(),
},
body: JSON.stringify({
description,
imageUrl,
}),
}).then((response) => {
if (response.status === 500) {
throw new Error("Ошибка сервера");
}
if (response.status === 401) {
throw new Error("Нет авторизации");
}
if (response.status === 400) {
throw new Error("Неверный запрос");
}
if (response.status === 201) {
return response.json();
}
});
}

export function registerUser({ login, password, name, imageUrl }) {
return fetch(baseHost + "/api/user", {
method: "POST",
Expand Down
61 changes: 52 additions & 9 deletions components/add-post-page-component.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,66 @@
import { onAddPostClick } from "../api.js";
import { renderUploadImageComponent } from "./upload-image-component.js";

export function renderAddPostPageComponent({ appEl, onAddPostClick }) {
const render = () => {
// @TODO: Реализовать страницу добавления поста
const appHtml = `
<div class="page-container">
<div class="header-container"></div>
Cтраница добавления поста
<button class="button" id="add-button">Добавить</button>
<div class="header-container">
<div class="page-header">
<h1 class="logo">instapro</h1>
<button class="header-button add-or-login-button">
<div title="Добавить пост" class="add-post-sign"></div>
</button>
<button title="Админ" class="header-button logout-button">Выйти</button>
</div>
</div>
`;
<div class="form">
<h3 class="form-title">Добавить пост</h3>
<div class="form-inputs">
<div class="upload-image-container">
<div class="upload=image">
<label class="file-upload-label secondary-button">
<input type="file" class="file-upload-input" style="display:none">
Выберите фото
</label>
</div>
</div>
<label>
Опишите фотографию:
<textarea class="input textarea" id="description" rows="4"></textarea>
</label>
<button class="button" id="add-button">Добавить</button>
</div>
</div>
</div>`;

appEl.innerHTML = appHtml;

document.getElementById("add-button").addEventListener("click", () => {
onAddPostClick({
description: "Описание картинки",
imageUrl: "https://image.png",
let imageUrl = "";
const descriptionEl = document.getElementById("description");
const uploadImageContainer = document.querySelector(
".upload-image-container",
);
const buttonAdd = document.getElementById("add-button");
if (uploadImageContainer) {
renderUploadImageComponent({
element: uploadImageContainer,
onImageUrlChange(newImageUrl) {
imageUrl = newImageUrl;
},
});
}
buttonAdd.addEventListener("click", () => {
if (!descriptionEl.value.trim() || imageUrl == "") {
alert("Заполните форму!");
return;
}
onAddPostClick(
descriptionEl.value.replaceAll("<", "&lt;").replaceAll(">", "&gt;"),
imageUrl,
);
});
};

render();
}
15 changes: 12 additions & 3 deletions components/auth-page-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,18 @@ export function renderAuthPageComponent({ appEl, setUser }) {
});
} else {
// Обработка регистрации
const login = document.getElementById("login-input").value;
const name = document.getElementById("name-input").value;
const password = document.getElementById("password-input").value;
const login = document
.getElementById("login-input")
.value.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
const name = document
.getElementById("name-input")
.value.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
const password = document
.getElementById("password-input")
.value.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");

if (!name) {
alert("Введите имя");
Expand Down
10 changes: 10 additions & 0 deletions components/formatDate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { formatDistanceToNow } from "../node_modules/date-fns/formatDistanceToNow.js";
import { ru } from "../node_modules/date-fns/locale/ru.js";

export function formatDate(date) {
return formatDistanceToNow(new Date(date), {
locale: ru,
includeSeconds: true,
addSuffix: true,
});
}
27 changes: 27 additions & 0 deletions components/likes-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { posts } from "../index.js";
import { renderPostsPageComponent } from "./posts-page-component.js";

export const putLike = (postId) => {
const likeButtons = document.querySelectorAll(".like-button");

for (const likeButton of likeButtons) {
likeButton.addEventListener("click", (event) => {
event.stopPropagation();
const postId = likeButton.dataset.postId;
const post = posts[index];

if (!post.isLiked) {
post.likes++;
post.isLiked = true;
} else {
post.likes--;
post.isLiked = false;
}

renderPostsPageComponent();
/*})
.catch((error) => {
console.error("Ошибка при постановке лайка:", error);*/
});
}
};
Loading