diff --git a/api.js b/api.js index 8997c44d..ee25b72f 100644 --- a/api.js +++ b/api.js @@ -1,7 +1,7 @@ // Замени на свой, чтобы получить независимый от других набор данных. // "боевая" версия инстапро лежит в ключе prod const personalKey = "prod"; -const baseHost = "https://webdev-hw-api.vercel.app"; +const baseHost = " https://wedev-api.sky.pro"; const postsHost = `${baseHost}/api/v1/${personalKey}/instapro`; export function getPosts({ token }) { @@ -19,6 +19,7 @@ export function getPosts({ token }) { return response.json(); }) .then((data) => { + console.log(data.posts); return data.posts; }); } @@ -33,12 +34,18 @@ export function registerUser({ login, password, name, imageUrl }) { name, imageUrl, }), - }).then((response) => { - if (response.status === 400) { - throw new Error("Такой пользователь уже существует"); - } - return response.json(); - }); + }) + .then((response) => { + if (response.status === 400) { + throw new Error("Такой пользователь уже существует"); + } + return response.json(); + }) + .catch((error) => { + if (error.message === "Такой пользователь уже существует") { + alert("Такой пользователь уже существует"); + } else alert("Кажется, у вас сломался интернет, попробуйте позже"); + }); } export function loginUser({ login, password }) { @@ -48,12 +55,18 @@ export function loginUser({ login, password }) { login, password, }), - }).then((response) => { - if (response.status === 400) { - throw new Error("Неверный логин или пароль"); - } - return response.json(); - }); + }) + .then((response) => { + if (response.status === 400) { + throw new Error("Неверный логин или пароль"); + } + return response.json(); + }) + .catch((error) => { + if (error.message === "Неверный логин или пароль") { + alert("Неверный логин или пароль"); + } else alert("Кажется, у вас сломался интернет, попробуйте позже"); + }); } // Загружает картинку в облако, возвращает url загруженной картинки @@ -68,3 +81,78 @@ export function uploadImage({ file }) { return response.json(); }); } + +export function addPost({ token, description, imageUrl }) { + return fetch(postsHost, { + method: "POST", + body: JSON.stringify({ + description, + imageUrl, + }), + headers: { + Authorization: token, + }, + }); +} + +export function getPostsUser({ id }) { + return fetch(postsHost + "/user-posts/" + id, { + method: "GET", + }) + .then((response) => { + if (response.status === 401) { + throw new Error("Нет авторизации"); + } + return response.json(); + }) + .then((data) => { + console.log(data.posts); + return data.posts; + }) + .catch((error) => { + if (error.message === "Нет авторизации") { + alert("Нет авторизации"); + } else alert("Кажется, у вас сломался интернет, попробуйте позже"); + }); +} + +export function likePost(token, id) { + return fetch(postsHost + `/${id}/like`, { + method: "POST", + headers: { + Authorization: token, + }, + }) + .then((response) => { + if (response.status === 401) { + throw new Error("Нет авторизации"); + } + + return response.json(); + }) + .catch((error) => { + if (error.message === "Нет авторизации") { + alert("Нет авторизации"); + } else alert("Кажется, у вас сломался интернет, попробуйте позже"); + }); +} +export function disLikePost(token, id) { + return fetch(postsHost + `/${id}/dislike`, { + method: "POST", + headers: { + Authorization: token, + }, + }) + .then((response) => { + if (response.status === 401) { + throw new Error("Нет авторизации"); + } + + return response.json(); + }) + .catch((error) => { + if (error.message === "Нет авторизации") { + alert("Нет авторизации"); + } else alert("Кажется, у вас сломался интернет, попробуйте позже"); + }); +} diff --git a/components/add-post-page-component.js b/components/add-post-page-component.js index 59554d86..22be4177 100644 --- a/components/add-post-page-component.js +++ b/components/add-post-page-component.js @@ -1,20 +1,53 @@ +import { renderHeaderComponent } from "./header-component.js"; +import { renderUploadImageComponent } from "./upload-image-component.js"; export function renderAddPostPageComponent({ appEl, onAddPostClick }) { const render = () => { + let imageUrl = ""; + // TODO: Реализовать страницу добавления поста const appHtml = `
-
- Cтраница добавления поста - -
+
+
+

+ Добавить пост +

+
+
+ + + + + +
+ + +
+
+ + `; appEl.innerHTML = appHtml; + renderHeaderComponent({ + element: document.querySelector(".header-container"), + }); + const uploadImageContainer = appEl.querySelector(".upload-image-container"); + + if (uploadImageContainer) { + renderUploadImageComponent({ + element: appEl.querySelector(".upload-image-container"), + onImageUrlChange(newImageUrl) { + imageUrl = newImageUrl; + }, + }); + } + const descriptionElement = document.getElementById("description"); document.getElementById("add-button").addEventListener("click", () => { onAddPostClick({ - description: "Описание картинки", - imageUrl: "https://image.png", + description: descriptionElement.value, + imageUrl: imageUrl, }); }); }; diff --git a/components/posts-page-component.js b/components/posts-page-component.js index 5b97fdfe..b958cfb1 100644 --- a/components/posts-page-component.js +++ b/components/posts-page-component.js @@ -1,97 +1,64 @@ import { USER_POSTS_PAGE } from "../routes.js"; import { renderHeaderComponent } from "./header-component.js"; import { posts, goToPage } from "../index.js"; +import { sanitizeHtml } from "../helpers.js"; +import { formatDistanceToNow } from "date-fns"; +import { ru } from "date-fns/locale"; +import { likePost, disLikePost } from "../api.js"; -export function renderPostsPageComponent({ appEl }) { +export function renderPostsPageComponent({ appEl, token }) { // TODO: реализовать рендер постов из api console.log("Актуальный список постов:", posts); - /** * TODO: чтобы отформатировать дату создания поста в виде "19 минут назад" * можно использовать https://date-fns.org/v2.29.3/docs/formatDistanceToNow */ - const appHtml = ` -
-
- -
`; + + const appHtml = posts.map((comment) => { + return `
+
+
`; + }); appEl.innerHTML = appHtml; @@ -106,4 +73,21 @@ export function renderPostsPageComponent({ appEl }) { }); }); } + + for (let likeButton of document.querySelectorAll(".like-button")) { + likeButton.addEventListener("click", async () => { + const likeImage = likeButton.querySelector("img"); + let commentID = likeButton.dataset.postid; + + if (likeImage.src.includes("like-active")) { + // Dislike post + await disLikePost(token, commentID); + likeImage.src = "../assets/images/like-not-active.svg"; + } else { + // Like post + await likePost(token, commentID); + likeImage.src = "../assets/images/like-active.svg"; + } + }); + } } diff --git a/dist/main.js b/dist/main.js new file mode 100644 index 00000000..c28c66fd --- /dev/null +++ b/dist/main.js @@ -0,0 +1,506 @@ +/* + * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). + * This devtool is neither made for production nor for readable output files. + * It uses "eval()" calls to create a separate source file in the browser devtools. + * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) + * or disable the default devtool with "devtool: false". + * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). + */ +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./api.js": +/*!****************!*\ + !*** ./api.js ***! + \****************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ addPost: () => (/* binding */ addPost),\n/* harmony export */ disLikePost: () => (/* binding */ disLikePost),\n/* harmony export */ getPosts: () => (/* binding */ getPosts),\n/* harmony export */ getPostsUser: () => (/* binding */ getPostsUser),\n/* harmony export */ likePost: () => (/* binding */ likePost),\n/* harmony export */ loginUser: () => (/* binding */ loginUser),\n/* harmony export */ registerUser: () => (/* binding */ registerUser),\n/* harmony export */ uploadImage: () => (/* binding */ uploadImage)\n/* harmony export */ });\n// Замени на свой, чтобы получить независимый от других набор данных.\r\n// \"боевая\" версия инстапро лежит в ключе prod\r\nconst personalKey = \"prod\";\r\nconst baseHost = \" https://wedev-api.sky.pro\";\r\nconst postsHost = `${baseHost}/api/v1/${personalKey}/instapro`;\r\n\r\nfunction getPosts({ token }) {\r\n return fetch(postsHost, {\r\n method: \"GET\",\r\n headers: {\r\n Authorization: token,\r\n },\r\n })\r\n .then((response) => {\r\n if (response.status === 401) {\r\n throw new Error(\"Нет авторизации\");\r\n }\r\n\r\n return response.json();\r\n })\r\n .then((data) => {\r\n console.log(data.posts);\r\n return data.posts;\r\n });\r\n}\r\n\r\n// https://github.com/GlebkaF/webdev-hw-api/blob/main/pages/api/user/README.md#%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%D1%81%D1%8F\r\nfunction registerUser({ login, password, name, imageUrl }) {\r\n return fetch(baseHost + \"/api/user\", {\r\n method: \"POST\",\r\n body: JSON.stringify({\r\n login,\r\n password,\r\n name,\r\n imageUrl,\r\n }),\r\n })\r\n .then((response) => {\r\n if (response.status === 400) {\r\n throw new Error(\"Такой пользователь уже существует\");\r\n }\r\n return response.json();\r\n })\r\n .catch((error) => {\r\n if (error.message === \"Такой пользователь уже существует\") {\r\n alert(\"Такой пользователь уже существует\");\r\n } else alert(\"Кажется, у вас сломался интернет, попробуйте позже\");\r\n });\r\n}\r\n\r\nfunction loginUser({ login, password }) {\r\n return fetch(baseHost + \"/api/user/login\", {\r\n method: \"POST\",\r\n body: JSON.stringify({\r\n login,\r\n password,\r\n }),\r\n })\r\n .then((response) => {\r\n if (response.status === 400) {\r\n throw new Error(\"Неверный логин или пароль\");\r\n }\r\n return response.json();\r\n })\r\n .catch((error) => {\r\n if (error.message === \"Неверный логин или пароль\") {\r\n alert(\"Неверный логин или пароль\");\r\n } else alert(\"Кажется, у вас сломался интернет, попробуйте позже\");\r\n });\r\n}\r\n\r\n// Загружает картинку в облако, возвращает url загруженной картинки\r\nfunction uploadImage({ file }) {\r\n const data = new FormData();\r\n data.append(\"file\", file);\r\n\r\n return fetch(baseHost + \"/api/upload/image\", {\r\n method: \"POST\",\r\n body: data,\r\n }).then((response) => {\r\n return response.json();\r\n });\r\n}\r\n\r\nfunction addPost({ token, description, imageUrl }) {\r\n return fetch(postsHost, {\r\n method: \"POST\",\r\n body: JSON.stringify({\r\n description,\r\n imageUrl,\r\n }),\r\n headers: {\r\n Authorization: token,\r\n },\r\n });\r\n}\r\n\r\nfunction getPostsUser({ id }) {\r\n return fetch(postsHost + \"/user-posts/\" + id, {\r\n method: \"GET\",\r\n })\r\n .then((response) => {\r\n if (response.status === 401) {\r\n throw new Error(\"Нет авторизации\");\r\n }\r\n return response.json();\r\n })\r\n .then((data) => {\r\n console.log(data.posts);\r\n return data.posts;\r\n })\r\n .catch((error) => {\r\n if (error.message === \"Нет авторизации\") {\r\n alert(\"Нет авторизации\");\r\n } else alert(\"Кажется, у вас сломался интернет, попробуйте позже\");\r\n });\r\n}\r\n\r\nfunction likePost(token, id) {\r\n return fetch(postsHost + `/${id}/like`, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: token,\r\n },\r\n })\r\n .then((response) => {\r\n if (response.status === 401) {\r\n throw new Error(\"Нет авторизации\");\r\n }\r\n\r\n return response.json();\r\n })\r\n .catch((error) => {\r\n if (error.message === \"Нет авторизации\") {\r\n alert(\"Нет авторизации\");\r\n } else alert(\"Кажется, у вас сломался интернет, попробуйте позже\");\r\n });\r\n}\r\nfunction disLikePost(token, id) {\r\n return fetch(postsHost + `/${id}/dislike`, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: token,\r\n },\r\n })\r\n .then((response) => {\r\n if (response.status === 401) {\r\n throw new Error(\"Нет авторизации\");\r\n }\r\n\r\n return response.json();\r\n })\r\n .catch((error) => {\r\n if (error.message === \"Нет авторизации\") {\r\n alert(\"Нет авторизации\");\r\n } else alert(\"Кажется, у вас сломался интернет, попробуйте позже\");\r\n });\r\n}\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./api.js?"); + +/***/ }), + +/***/ "./components/add-post-page-component.js": +/*!***********************************************!*\ + !*** ./components/add-post-page-component.js ***! + \***********************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ renderAddPostPageComponent: () => (/* binding */ renderAddPostPageComponent)\n/* harmony export */ });\n/* harmony import */ var _header_component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./header-component.js */ \"./components/header-component.js\");\n/* harmony import */ var _upload_image_component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./upload-image-component.js */ \"./components/upload-image-component.js\");\n\r\n\r\nfunction renderAddPostPageComponent({ appEl, onAddPostClick }) {\r\n const render = () => {\r\n let imageUrl = \"\";\r\n\r\n // TODO: Реализовать страницу добавления поста\r\n const appHtml = `\r\n
\r\n
\r\n
\r\n

\r\n Добавить пост\r\n

\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n `;\r\n\r\n appEl.innerHTML = appHtml;\r\n (0,_header_component_js__WEBPACK_IMPORTED_MODULE_0__.renderHeaderComponent)({\r\n element: document.querySelector(\".header-container\"),\r\n });\r\n const uploadImageContainer = appEl.querySelector(\".upload-image-container\");\r\n\r\n if (uploadImageContainer) {\r\n (0,_upload_image_component_js__WEBPACK_IMPORTED_MODULE_1__.renderUploadImageComponent)({\r\n element: appEl.querySelector(\".upload-image-container\"),\r\n onImageUrlChange(newImageUrl) {\r\n imageUrl = newImageUrl;\r\n },\r\n });\r\n }\r\n const descriptionElement = document.getElementById(\"description\");\r\n\r\n document.getElementById(\"add-button\").addEventListener(\"click\", () => {\r\n onAddPostClick({\r\n description: descriptionElement.value,\r\n imageUrl: imageUrl,\r\n });\r\n });\r\n };\r\n\r\n render();\r\n}\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./components/add-post-page-component.js?"); + +/***/ }), + +/***/ "./components/auth-page-component.js": +/*!*******************************************!*\ + !*** ./components/auth-page-component.js ***! + \*******************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ renderAuthPageComponent: () => (/* binding */ renderAuthPageComponent)\n/* harmony export */ });\n/* harmony import */ var _api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../api.js */ \"./api.js\");\n/* harmony import */ var _header_component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./header-component.js */ \"./components/header-component.js\");\n/* harmony import */ var _upload_image_component_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./upload-image-component.js */ \"./components/upload-image-component.js\");\n\r\n\r\n\r\n\r\nfunction renderAuthPageComponent({ appEl, setUser }) {\r\n let isLoginMode = true;\r\n let imageUrl = \"\";\r\n\r\n const renderForm = () => {\r\n const appHtml = `\r\n
\r\n
\r\n
\r\n

\r\n ${\r\n isLoginMode\r\n ? \"Вход в Instapro\"\r\n : \"Регистрация в Instapro\"\r\n }\r\n

\r\n
\r\n \r\n ${\r\n !isLoginMode\r\n ? `\r\n
\r\n \r\n `\r\n : \"\"\r\n }\r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n`;\r\n\r\n appEl.innerHTML = appHtml;\r\n\r\n // Не вызываем перерендер, чтобы не сбрасывалась заполненная форма\r\n // Точечно обновляем кусочек дом дерева\r\n const setError = (message) => {\r\n appEl.querySelector(\".form-error\").textContent = message;\r\n };\r\n\r\n (0,_header_component_js__WEBPACK_IMPORTED_MODULE_1__.renderHeaderComponent)({\r\n element: document.querySelector(\".header-container\"),\r\n });\r\n\r\n const uploadImageContainer = appEl.querySelector(\".upload-image-container\");\r\n\r\n if (uploadImageContainer) {\r\n (0,_upload_image_component_js__WEBPACK_IMPORTED_MODULE_2__.renderUploadImageComponent)({\r\n element: appEl.querySelector(\".upload-image-container\"),\r\n onImageUrlChange(newImageUrl) {\r\n imageUrl = newImageUrl;\r\n },\r\n });\r\n }\r\n\r\n document.getElementById(\"login-button\").addEventListener(\"click\", () => {\r\n setError(\"\");\r\n\r\n if (isLoginMode) {\r\n const login = document.getElementById(\"login-input\").value;\r\n const password = document.getElementById(\"password-input\").value;\r\n\r\n if (!login) {\r\n alert(\"Введите логин\");\r\n return;\r\n }\r\n\r\n if (!password) {\r\n alert(\"Введите пароль\");\r\n return;\r\n }\r\n\r\n (0,_api_js__WEBPACK_IMPORTED_MODULE_0__.loginUser)({\r\n login: login,\r\n password: password,\r\n })\r\n .then((user) => {\r\n setUser(user.user);\r\n })\r\n .catch((error) => {\r\n console.warn(error);\r\n setError(error.message);\r\n });\r\n } else {\r\n const login = document.getElementById(\"login-input\").value;\r\n const name = document.getElementById(\"name-input\").value;\r\n const password = document.getElementById(\"password-input\").value;\r\n if (!name) {\r\n alert(\"Введите имя\");\r\n return;\r\n }\r\n if (!login) {\r\n alert(\"Введите логин\");\r\n return;\r\n }\r\n\r\n if (!password) {\r\n alert(\"Введите пароль\");\r\n return;\r\n }\r\n\r\n if (!imageUrl) {\r\n alert(\"Не выбрана фотография\");\r\n return;\r\n }\r\n\r\n (0,_api_js__WEBPACK_IMPORTED_MODULE_0__.registerUser)({\r\n login: login,\r\n password: password,\r\n name: name,\r\n imageUrl,\r\n })\r\n .then((user) => {\r\n setUser(user.user);\r\n })\r\n .catch((error) => {\r\n console.warn(error);\r\n setError(error.message);\r\n });\r\n }\r\n });\r\n\r\n document.getElementById(\"toggle-button\").addEventListener(\"click\", () => {\r\n isLoginMode = !isLoginMode;\r\n renderForm();\r\n });\r\n };\r\n\r\n renderForm();\r\n}\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./components/auth-page-component.js?"); + +/***/ }), + +/***/ "./components/header-component.js": +/*!****************************************!*\ + !*** ./components/header-component.js ***! + \****************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ renderHeaderComponent: () => (/* binding */ renderHeaderComponent)\n/* harmony export */ });\n/* harmony import */ var _index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../index.js */ \"./index.js\");\n/* harmony import */ var _routes_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../routes.js */ \"./routes.js\");\n\r\n\r\n\r\nfunction renderHeaderComponent({ element }) {\r\n element.innerHTML = `\r\n
\r\n

instapro

\r\n \r\n ${\r\n _index_js__WEBPACK_IMPORTED_MODULE_0__.user\r\n ? ``\r\n : \"\"\r\n } \r\n
\r\n \r\n`;\r\n\r\n element\r\n .querySelector(\".add-or-login-button\")\r\n .addEventListener(\"click\", () => {\r\n if (_index_js__WEBPACK_IMPORTED_MODULE_0__.user) {\r\n (0,_index_js__WEBPACK_IMPORTED_MODULE_0__.goToPage)(_routes_js__WEBPACK_IMPORTED_MODULE_1__.ADD_POSTS_PAGE);\r\n } else {\r\n (0,_index_js__WEBPACK_IMPORTED_MODULE_0__.goToPage)(_routes_js__WEBPACK_IMPORTED_MODULE_1__.AUTH_PAGE);\r\n }\r\n });\r\n\r\n element.querySelector(\".logo\").addEventListener(\"click\", () => {\r\n (0,_index_js__WEBPACK_IMPORTED_MODULE_0__.goToPage)(_routes_js__WEBPACK_IMPORTED_MODULE_1__.POSTS_PAGE);\r\n });\r\n\r\n element.querySelector(\".logout-button\")?.addEventListener(\"click\", _index_js__WEBPACK_IMPORTED_MODULE_0__.logout);\r\n\r\n return element;\r\n}\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./components/header-component.js?"); + +/***/ }), + +/***/ "./components/loading-page-component.js": +/*!**********************************************!*\ + !*** ./components/loading-page-component.js ***! + \**********************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ renderLoadingPageComponent: () => (/* binding */ renderLoadingPageComponent)\n/* harmony export */ });\n/* harmony import */ var _header_component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./header-component.js */ \"./components/header-component.js\");\n\r\n\r\nfunction renderLoadingPageComponent({ appEl, user, goToPage }) {\r\n const appHtml = `\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
`;\r\n\r\n appEl.innerHTML = appHtml;\r\n\r\n (0,_header_component_js__WEBPACK_IMPORTED_MODULE_0__.renderHeaderComponent)({\r\n user,\r\n element: document.querySelector(\".header-container\"),\r\n goToPage,\r\n });\r\n}\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./components/loading-page-component.js?"); + +/***/ }), + +/***/ "./components/posts-page-component.js": +/*!********************************************!*\ + !*** ./components/posts-page-component.js ***! + \********************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ renderPostsPageComponent: () => (/* binding */ renderPostsPageComponent)\n/* harmony export */ });\n/* harmony import */ var _routes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../routes.js */ \"./routes.js\");\n/* harmony import */ var _header_component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./header-component.js */ \"./components/header-component.js\");\n/* harmony import */ var _index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../index.js */ \"./index.js\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../helpers.js */ \"./helpers.js\");\n/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! date-fns */ \"./node_modules/date-fns/formatDistanceToNow.mjs\");\n/* harmony import */ var date_fns_locale__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! date-fns/locale */ \"./node_modules/date-fns/locale/ru.mjs\");\n/* harmony import */ var _api_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../api.js */ \"./api.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction renderPostsPageComponent({ appEl, token }) {\r\n // TODO: реализовать рендер постов из api\r\n console.log(\"Актуальный список постов:\", _index_js__WEBPACK_IMPORTED_MODULE_2__.posts);\r\n /**\r\n * TODO: чтобы отформатировать дату создания поста в виде \"19 минут назад\"\r\n * можно использовать https://date-fns.org/v2.29.3/docs/formatDistanceToNow\r\n */\r\n\r\n const appHtml = _index_js__WEBPACK_IMPORTED_MODULE_2__.posts.map((comment) => {\r\n return `
\r\n
\r\n
`;\r\n });\r\n\r\n appEl.innerHTML = appHtml;\r\n\r\n (0,_header_component_js__WEBPACK_IMPORTED_MODULE_1__.renderHeaderComponent)({\r\n element: document.querySelector(\".header-container\"),\r\n });\r\n\r\n for (let userEl of document.querySelectorAll(\".post-header\")) {\r\n userEl.addEventListener(\"click\", () => {\r\n (0,_index_js__WEBPACK_IMPORTED_MODULE_2__.goToPage)(_routes_js__WEBPACK_IMPORTED_MODULE_0__.USER_POSTS_PAGE, {\r\n userId: userEl.dataset.userId,\r\n });\r\n });\r\n }\r\n\r\n for (let likeButton of document.querySelectorAll(\".like-button\")) {\r\n likeButton.addEventListener(\"click\", async () => {\r\n const likeImage = likeButton.querySelector(\"img\");\r\n let commentID = likeButton.dataset.postid;\r\n\r\n if (likeImage.src.includes(\"like-active\")) {\r\n // Dislike post\r\n await (0,_api_js__WEBPACK_IMPORTED_MODULE_4__.disLikePost)(token, commentID);\r\n likeImage.src = \"../assets/images/like-not-active.svg\";\r\n } else {\r\n // Like post\r\n await (0,_api_js__WEBPACK_IMPORTED_MODULE_4__.likePost)(token, commentID);\r\n likeImage.src = \"../assets/images/like-active.svg\";\r\n }\r\n });\r\n }\r\n}\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./components/posts-page-component.js?"); + +/***/ }), + +/***/ "./components/upload-image-component.js": +/*!**********************************************!*\ + !*** ./components/upload-image-component.js ***! + \**********************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ renderUploadImageComponent: () => (/* binding */ renderUploadImageComponent)\n/* harmony export */ });\n/* harmony import */ var _api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../api.js */ \"./api.js\");\n\r\n\r\nfunction renderUploadImageComponent({ element, onImageUrlChange }) {\r\n let imageUrl = \"\";\r\n\r\n const render = () => {\r\n element.innerHTML = `\r\n
\r\n ${\r\n imageUrl\r\n ? `\r\n
\r\n \r\n \r\n
\r\n `\r\n : `\r\n \r\n \r\n `\r\n }\r\n
\r\n`;\r\n\r\n const fileInputElement = element.querySelector(\".file-upload-input\");\r\n\r\n fileInputElement?.addEventListener(\"change\", () => {\r\n const file = fileInputElement.files[0];\r\n if (file) {\r\n const lableEl = document.querySelector(\".file-upload-label\");\r\n lableEl.setAttribute(\"disabled\", true);\r\n lableEl.textContent = \"Загружаю файл...\";\r\n (0,_api_js__WEBPACK_IMPORTED_MODULE_0__.uploadImage)({ file }).then(({ fileUrl }) => {\r\n imageUrl = fileUrl;\r\n onImageUrlChange(imageUrl);\r\n render();\r\n });\r\n }\r\n });\r\n\r\n element\r\n .querySelector(\".file-upload-remove-button\")\r\n ?.addEventListener(\"click\", () => {\r\n imageUrl = \"\";\r\n onImageUrlChange(imageUrl);\r\n render();\r\n });\r\n };\r\n\r\n render();\r\n}\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./components/upload-image-component.js?"); + +/***/ }), + +/***/ "./helpers.js": +/*!********************!*\ + !*** ./helpers.js ***! + \********************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ getUserFromLocalStorage: () => (/* binding */ getUserFromLocalStorage),\n/* harmony export */ removeUserFromLocalStorage: () => (/* binding */ removeUserFromLocalStorage),\n/* harmony export */ sanitizeHtml: () => (/* binding */ sanitizeHtml),\n/* harmony export */ saveUserToLocalStorage: () => (/* binding */ saveUserToLocalStorage)\n/* harmony export */ });\nfunction saveUserToLocalStorage(user) {\r\n window.localStorage.setItem(\"user\", JSON.stringify(user));\r\n}\r\n\r\nfunction getUserFromLocalStorage(user) {\r\n try {\r\n return JSON.parse(window.localStorage.getItem(\"user\"));\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\nfunction removeUserFromLocalStorage(user) {\r\n window.localStorage.removeItem(\"user\");\r\n}\r\n\r\nconst sanitizeHtml = (htmlString) => {\r\n return htmlString\r\n .replaceAll(\"&\", \"&\")\r\n .replaceAll(\"<\", \"<\")\r\n .replaceAll(\">\", \">\")\r\n .replaceAll('\"', \""\");\r\n};\r\n\n\n//# sourceURL=webpack://webdev-cw-instapro/./helpers.js?"); + +/***/ }), + +/***/ "./index.js": +/*!******************!*\ + !*** ./index.js ***! + \******************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ goToPage: () => (/* binding */ goToPage),\n/* harmony export */ logout: () => (/* binding */ logout),\n/* harmony export */ page: () => (/* binding */ page),\n/* harmony export */ posts: () => (/* binding */ posts),\n/* harmony export */ user: () => (/* binding */ user)\n/* harmony export */ });\n/* harmony import */ var _api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./api.js */ \"./api.js\");\n/* harmony import */ var _components_add_post_page_component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/add-post-page-component.js */ \"./components/add-post-page-component.js\");\n/* harmony import */ var _components_auth_page_component_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/auth-page-component.js */ \"./components/auth-page-component.js\");\n/* harmony import */ var date_fns_locale__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! date-fns/locale */ \"./node_modules/date-fns/locale/ru.mjs\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./helpers.js */ \"./helpers.js\");\n/* harmony import */ var date_fns__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! date-fns */ \"./node_modules/date-fns/formatDistanceToNow.mjs\");\n/* harmony import */ var _components_header_component_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/header-component.js */ \"./components/header-component.js\");\n/* harmony import */ var _routes_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./routes.js */ \"./routes.js\");\n/* harmony import */ var _components_posts_page_component_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/posts-page-component.js */ \"./components/posts-page-component.js\");\n/* harmony import */ var _components_loading_page_component_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/loading-page-component.js */ \"./components/loading-page-component.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nlet user = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.getUserFromLocalStorage)();\r\nlet page = null;\r\nlet posts = [];\r\n\r\nconst getToken = () => {\r\n const token = user ? `Bearer ${user.token}` : undefined;\r\n return token;\r\n};\r\n\r\nconst logout = () => {\r\n user = null;\r\n (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.removeUserFromLocalStorage)();\r\n goToPage(_routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE);\r\n};\r\n\r\n/**\r\n * Включает страницу приложения\r\n */\r\nconst goToPage = async (newPage, data) => {\r\n if (\r\n [\r\n _routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE,\r\n _routes_js__WEBPACK_IMPORTED_MODULE_5__.AUTH_PAGE,\r\n _routes_js__WEBPACK_IMPORTED_MODULE_5__.ADD_POSTS_PAGE,\r\n _routes_js__WEBPACK_IMPORTED_MODULE_5__.USER_POSTS_PAGE,\r\n _routes_js__WEBPACK_IMPORTED_MODULE_5__.LOADING_PAGE,\r\n ].includes(newPage)\r\n ) {\r\n if (newPage === _routes_js__WEBPACK_IMPORTED_MODULE_5__.ADD_POSTS_PAGE) {\r\n // Если пользователь не авторизован, то отправляем его на авторизацию перед добавлением поста\r\n page = user ? _routes_js__WEBPACK_IMPORTED_MODULE_5__.ADD_POSTS_PAGE : _routes_js__WEBPACK_IMPORTED_MODULE_5__.AUTH_PAGE;\r\n return renderApp();\r\n }\r\n\r\n if (newPage === _routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE) {\r\n page = _routes_js__WEBPACK_IMPORTED_MODULE_5__.LOADING_PAGE;\r\n renderApp();\r\n\r\n return (0,_api_js__WEBPACK_IMPORTED_MODULE_0__.getPosts)({ token: getToken() })\r\n .then((newPosts) => {\r\n page = _routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE;\r\n posts = newPosts;\r\n renderApp();\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n goToPage(_routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE);\r\n });\r\n }\r\n\r\n if (newPage === _routes_js__WEBPACK_IMPORTED_MODULE_5__.USER_POSTS_PAGE) {\r\n // TODO: реализовать получение постов юзера из API\r\n let id = data.userId;\r\n console.log(\"Открываю страницу пользователя: \", data.userId);\r\n posts = await (0,_api_js__WEBPACK_IMPORTED_MODULE_0__.getPostsUser)({ id });\r\n page = _routes_js__WEBPACK_IMPORTED_MODULE_5__.USER_POSTS_PAGE;\r\n return renderApp();\r\n }\r\n\r\n page = newPage;\r\n renderApp();\r\n\r\n return;\r\n }\r\n\r\n throw new Error(\"страницы не существует\");\r\n};\r\n\r\nconst renderApp = () => {\r\n const appEl = document.getElementById(\"app\");\r\n if (page === _routes_js__WEBPACK_IMPORTED_MODULE_5__.LOADING_PAGE) {\r\n return (0,_components_loading_page_component_js__WEBPACK_IMPORTED_MODULE_7__.renderLoadingPageComponent)({\r\n appEl,\r\n user,\r\n goToPage,\r\n });\r\n }\r\n\r\n if (page === _routes_js__WEBPACK_IMPORTED_MODULE_5__.AUTH_PAGE) {\r\n return (0,_components_auth_page_component_js__WEBPACK_IMPORTED_MODULE_2__.renderAuthPageComponent)({\r\n appEl,\r\n setUser: (newUser) => {\r\n user = newUser;\r\n (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.saveUserToLocalStorage)(user);\r\n goToPage(_routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE);\r\n },\r\n user,\r\n goToPage,\r\n });\r\n }\r\n\r\n if (page === _routes_js__WEBPACK_IMPORTED_MODULE_5__.ADD_POSTS_PAGE) {\r\n return (0,_components_add_post_page_component_js__WEBPACK_IMPORTED_MODULE_1__.renderAddPostPageComponent)({\r\n appEl,\r\n onAddPostClick({ description, imageUrl }) {\r\n // TODO: реализовать добавление поста в API\r\n (0,_api_js__WEBPACK_IMPORTED_MODULE_0__.addPost)({ token: getToken(), description, imageUrl });\r\n console.log(\"Добавляю пост...\", { description, imageUrl });\r\n goToPage(_routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE);\r\n },\r\n });\r\n }\r\n\r\n if (page === _routes_js__WEBPACK_IMPORTED_MODULE_5__.POSTS_PAGE) {\r\n return (0,_components_posts_page_component_js__WEBPACK_IMPORTED_MODULE_6__.renderPostsPageComponent)({\r\n appEl,\r\n token: getToken(),\r\n });\r\n }\r\n\r\n if (page === _routes_js__WEBPACK_IMPORTED_MODULE_5__.USER_POSTS_PAGE) {\r\n // TODO: реализовать страницу фотографию пользвателя\r\n\r\n const appHtml = posts.map((comment) => {\r\n return `\r\n