Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# Instapro

MVP социальной сети для обмена фотографиями
Реализовано:
страница добалнения поста
функционал лайков
страница автора поста
получение списка постов по API

## Первоначальная оценка

40 часов

## Фактически затраченное время

YYYY часов
38 часов

Доп. функции не реализовывались...
98 changes: 95 additions & 3 deletions api.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// Замени на свой, чтобы получить независимый от других набор данных.
// "боевая" версия инстапро лежит в ключе prod
const personalKey = "prod";
const baseHost = "https://webdev-hw-api.vercel.app";
const postsHost = `${baseHost}/api/v1/${personalKey}/instapro`;
Expand All @@ -23,6 +21,39 @@ export function getPosts({ token }) {
});
}

export function addPost({ token, description, imageUrl }) {
const url = `${baseHost}/api/v1/${personalKey}/instapro`;

if (!description || !imageUrl) {
throw new Error("Необходимо передать описание и ссылку на изображение");
}

return fetch(url, {
method: "POST",
headers: {
"Authorization": token,
},
body: JSON.stringify({ description, imageUrl }),
})
.then((response) => {
console.log("Статус ответа:", response.status);
if (!response.ok) {
return response.text().then((text) => {
throw new Error(`Ошибка при добавлении поста: ${text}`);
});
}
return response.json();
})
.then((data) => {
console.log("Пост успешно добавлен:", data);
return data;
})
.catch((error) => {
console.error("Ошибка при добавлении поста:", error);
throw error;
});
}

export function registerUser({ login, password, name, imageUrl }) {
return fetch(baseHost + "/api/user", {
method: "POST",
Expand Down Expand Up @@ -55,7 +86,6 @@ export function loginUser({ login, password }) {
});
}

// Загружает картинку в облако, возвращает url загруженной картинки
export function uploadImage({ file }) {
const data = new FormData();
data.append("file", file);
Expand All @@ -67,3 +97,65 @@ export function uploadImage({ file }) {
return response.json();
});
}

export function getUserPosts({ token, userId }) {
return fetch(`${postsHost}/user-posts/${userId}`, {
method: "GET",
headers: {
Authorization: token,
},
})
.then((response) => {
if (!response.ok) {
throw new Error("Ошибка загрузки постов пользователя");
}
return response.json();
})
.then((data) => data.posts);
}

export function likePost({ postId, token }) {
return fetch(`${postsHost}/${postId}/like`, {
method: "POST",
headers: {
Authorization: token,
},
}).then((response) => {
if (!response.ok) {
throw new Error("Ошибка при лайке поста");
}
return response.json();
});
}

export function dislikePost({ postId, token }) {
return fetch(`${postsHost}/${postId}/dislike`, {
method: "POST",
headers: {
Authorization: token,
},
}).then((response) => {
if (!response.ok) {
throw new Error("Ошибка при дизлайке поста");
}
return response.json();
});
}

export function toggleLike({ postId, token, isLiked }) {
const url = `${postsHost}/${postId}/${isLiked ? "dislike" : "like"}`;

console.log(`Sending request to: ${url}`);

return fetch(url, {
method: "POST",
headers: {
Authorization: token,
},
}).then((response) => {
if (!response.ok) {
throw new Error("Ошибка при лайке поста");
}
return response.json();
});
}
62 changes: 50 additions & 12 deletions components/add-post-page-component.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,59 @@
import { renderHeaderComponent } from "./header-component.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>
`;

<div class="page-container">
<div class="header-container"></div>
<div class="form">
<h3 class="form-title">Добавить пост</h3>
<div class="form-inputs">
<div class="upload-image-container">
</div>
<label>
Опишите фотографию:
<textarea class="input textarea" id="post-description" rows="4"></textarea>
</label>
<button class="button center" id="add-button">Добавить</button>
</div>
</div>
</div>
`;
appEl.innerHTML = appHtml;

document.getElementById("add-button").addEventListener("click", () => {
onAddPostClick({
description: "Описание картинки",
imageUrl: "https://image.png",
renderHeaderComponent({
element: document.querySelector(".header-container"),
});

let previewUrl = null;

const uploadImageContainer = appEl.querySelector(".upload-image-container");
if (uploadImageContainer) {
renderUploadImageComponent({
element: uploadImageContainer,
onImageUrlChange(newImageUrl) {
previewUrl = newImageUrl;
},
});
}

document.getElementById("add-button").addEventListener("click", () => {
const description = document
.getElementById("post-description")
.value.trim();

if (!previewUrl) {
alert("Пожалуйста, выберите фото");
return;
}

if (!description) {
alert("Пожалуйста, добавьте описание");
return;
}

onAddPostClick({ description, imageUrl: previewUrl });
});
};

Expand Down
Loading