diff --git a/README.md b/README.md index 34719e139..26c8b4ddf 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,115 @@ MVP социальной сети для обмена фотографиями ## Первоначальная оценка -ХХХХ часов +Много много часов ## Фактически затраченное время YYYY часов + +Сhecklist @TODO + +index.js +1) // @@TODO: реализовать получение постов юзера из API ГОТОВО + +2) // @TODO: реализовать добавление поста в API ГОТОВО + +3) // @TODO: реализовать страницу с фотографиями отдельного пользвателя ГОТОВО + +add-post-page-component.js +4) // @TODO: Реализовать страницу добавления поста ГОТОВО + +posts-page-component.js +5) // @TODO: реализовать рендер постов из api - ГОТОВО + +6) @TODO: чтобы отформатировать дату создания поста в виде "19 минут назад" можно использовать https://date-fns.org/v2.29.3/docs/formatDistanceToNow ГОТОВО + +Анализ архитектуры работы и последовательности действий + +Структура проекта +Project/ +|- api.js - работа с сервером (запросы GET, POST, загрузка файлов). +|- favicon.ico +|- helpers.js - вспомогательные функции (работа с LocalStorage для сохранения данных пользователя) +|- index.html - оболочка +|- index.js - управление рендером и навигацией @TODO #1-3 +|- README.md +|- routes.js - маршрутизатор +|- styles.css +|- ui-kit.css - стили кнопок инпутов и шрифтов +|- assets/ +| |- fonts/ +| | |- stratosskyengweb-medium.woff2 +| | |- stratosskyengweb-regular.woff2 +| |- images/ +| |- like-active.svg +| |- like-not-active.svg +|── components/ + |- add-post-page-component.js - создание нового поста @TODO #4 + |- auth-page-component.js - вход и регистрация + |- header-component.js - шапка (навигация, логин, кнопки входа и выхода) + |- loading-page-component.js - спинер загрузки данных с сервера + |- posts-page-component.js - главная страница, рендер постов @TODO #5 и 6 + |- upload-image-component.js - загрузка фоток + + КАК ЭТО РАБОТАЕТ + +1) index.html запускает index.js. +2) он в свою очередь определяет, на какой странице мы находимся (переменная page). Это либо: +- AUTH_PAGE - страница авторизации. +- ADD_POSTS_PAGE - добавление поста, +- POSTS_PAGE, основная страница ну или +- USER_POSTS_PAGE - профиль пользователя. +3) Если мы на POSTS_PAGE или USER_POSTS_PAGE то нужны данные пользователя или сами посты, тогда вызывается функция из api.js. +Пока мы ее ждем запускается LOADING_PAGE - спинер +4) Когда мы их получили, index.js вызывает нужный нам component/ +- AUTH_PAGE - renderAuthPageComponent +- ADD_POSTS_PAGE - renderAddPostPageComponent @TODO #2 +- POSTS_PAGE - renderPostsPageComponent +- USER_POSTS_PAGE - здесь заглушка @TODO #1 и 3 +5) И он уже генерирует HTML-строку и вставляет её в appEl.innerHTML внутри оболочки index.html. + +ИТАК ПЛАН РАБОТЫ +1) Пока лента статична я не увижу динамику Оживить ленту в posts-page-component.js +@TODO: реализовать рендер постов из api + +Удаляем статичный HTML сохранив шаблон post. Добавляем map для связи с массивом posts который приходит из index.js и превращаем массив в строку HTML. + +2) Профиль пользователя: +index.js +- @TODO: реализовать получение постов юзера из API +- @TODO: реализовать страницу с фотографиями отдельного пользвателя + +Добявляем в api.js функцию getUserPosts для получения постов от конкретного пользователя и отправляем ее в index.js + +Меняем логику получения постов для USER_POSTS_PAGE + +3) Интерфейс создания поста: +add-post-page-component.js +@TODO: Реализовать страницу добавления поста + +- Добавляем разметку страницы добавления поста +- Добовляем шапку +- И форму выбора фото с валидацией +- И О Чудо активировались страницы входа и регистрации + +4) Теперь публикация. Возвращаемся в index.js - @TODO: реализовать добавление поста в API + +В api добавляем функцию создания поста addPost +В index добавляем импорт из нее и вызываем функцию в ADD_POSTS_PAGE + + + +5) И в конце когда все будет работать мы можем внести правку в posts-page-component.js @TODO: чтобы отформатировать дату создания поста в виде "19 минут назад" можно использовать https://date-fns.org/v2.29.3/docs/formatDistanceToNow + +Подключил библиотеки для локолизации и форматирования даты публикации + +ФИНАЛ Доп задание - Лайки +Лайки можно ставить и удалять +api добавим функции POST и DELETE + +Импортируем функции в posts-page-component +Добовляем обработчик кликов +если не авторизован то ошибка в алерт + +ГОТОВО \ No newline at end of file diff --git a/api.js b/api.js index 123a9e3b6..4fa16545e 100644 --- a/api.js +++ b/api.js @@ -1,9 +1,28 @@ // Замени на свой, чтобы получить независимый от других набор данных. -// "боевая" версия инстапро лежит в ключе prod const personalKey = "prod"; const baseHost = "https://webdev-hw-api.vercel.app"; const postsHost = `${baseHost}/api/v1/${personalKey}/instapro`; +// Функция создания поста +export function addPost({ token, description, imageUrl }) { + return fetch(postsHost, { + method: "POST", + body: JSON.stringify({ + description, + imageUrl, + }), + headers: { + Authorization: token, + }, + }).then((response) => { + if (response.status === 400) { + throw new Error("Заполните описание и выберите картинку"); + } + return response.json(); + }); +} + +// Функция получения постов конкретного пользователя export function getPosts({ token }) { return fetch(postsHost, { method: "GET", @@ -15,7 +34,24 @@ export function getPosts({ token }) { if (response.status === 401) { throw new Error("Нет авторизации"); } + return response.json(); + }) + .then((data) => { + return data.posts; + }); +} +export function getUserPosts({ token, userId }) { + return fetch(postsHost + "/user-posts/" + userId, { + method: "GET", + headers: { + Authorization: token, + }, + }) + .then((response) => { + if (response.status === 401) { + throw new Error("Нет авторизации"); + } return response.json(); }) .then((data) => { @@ -55,6 +91,23 @@ export function loginUser({ login, password }) { }); } +// Ставим лайк +export function likePost({ token, postId }) { + return fetch(`${postsHost}/${postId}/like`, { + method: "POST", + headers: { Authorization: token } + }).then((response) => response.json()); +} + +// Удаляем лайк +export function dislikePost({ token, postId }) { + return fetch(`${postsHost}/${postId}/dislike`, { + method: "POST", // Странно но удаление тоже через POST + headers: { Authorization: token } + }).then((response) => response.json()); +} + + // Загружает картинку в облако, возвращает url загруженной картинки export function uploadImage({ file }) { const data = new FormData(); @@ -66,4 +119,4 @@ export function uploadImage({ file }) { }).then((response) => { return response.json(); }); -} +} \ No newline at end of file diff --git a/components/add-post-page-component.js b/components/add-post-page-component.js index 8277f093b..a6b6e996d 100644 --- a/components/add-post-page-component.js +++ b/components/add-post-page-component.js @@ -1,20 +1,70 @@ +import { renderHeaderComponent } from "./header-component.js"; +import { renderUploadImageComponent } from "./upload-image-component.js"; + export function renderAddPostPageComponent({ appEl, onAddPostClick }) { + // Переменная хранения ссылки на фото + let imageUrl = ""; + const render = () => { // @TODO: Реализовать страницу добавления поста + // Основная разметка страницы const appHtml = ` -
${post.user.name}
++ Нравится: ${post.likes.length} +
++ ${post.user.name} + ${post.description} +
++ ${createDate} +
+
- Иван Иваныч
-
- - Нравится: 2 -
-- Иван Иваныч - Ромашка, ромашка... -
-- 19 минут назад -
-
- Варварва Н.
-
- - Нравится: 35 -
-- Варварва Н. - Нарисовала картину, посмотрите какая красивая -
-- 3 часа назад -
-
- Варварва Н.
-- Нравится: 0 -
-- Варварва Н. - Голова -
-- 8 дней назад -
-