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
16 changes: 16 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["eslint:recommended"],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "warn",
"no-console": "warn",
"prefer-const": "error"
}
}
8 changes: 8 additions & 0 deletions .prettierrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false
}
269 changes: 12 additions & 257 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,16 @@
</head>

<body>
<div class="container">
<ul class="comments">
<li class="comment">
<div class="comment-header">
<div>Глеб Фокин</div>
<div>12.02.22 12:18</div>
</div>
<div class="comment-body">
<div class="comment-text">
Это будет первый комментарий на этой странице
</div>
</div>
<div class="comment-footer">
<div class="likes">
<span class="likes-counter">3</span>
<button class="like-button"></button>
</div>
</div>
</li>
<li class="comment">
<div class="comment-header">
<div>Варвара Н.</div>
<div>13.02.22 19:22</div>
</div>
<div class="comment-body">
<div class="comment-text">
Мне нравится как оформлена эта страница! ❤
</div>
</div>
<div class="comment-footer">
<div class="likes">
<span class="likes-counter">75</span>
<button class="like-button -active-like"></button>
</div>
</div>
</li>
</ul>
<div class="container">
<div class="comments-container">
<div id="loading" class="loading">Загрузка комментариев...</div>
<ul class="comments" style="display: none;">
</ul>
<div id="error-message" class="error-message" style="display: none;">
Не удалось загрузить комментарии.
<button id="retry-button">Попробовать снова</button>
</div>
</div>
<div class="add-form">
<input
type="text"
Expand All @@ -53,232 +26,14 @@
<textarea
type="textarea"
class="add-form-text"
placeholder="Введите ваш коментарий"
placeholder="Введите ваш комментарий"
rows="4"
></textarea>
<div class="add-form-row">
<button class="add-form-button">Написать</button>
</div>
</div>
</div>
<script type="module" src="main.js"></script>
</body>

<script>

const host = "https://wedev-api.sky.pro/api/v1/dmitriy-skachkov"

const fetchComments = () => {
return fetch(host + "/comments").then(res => {
if (!res.ok) {
throw new Error('Ошибка загрузки комментариев');
}
return res.json()
})
.then((responseData) => {
const appComments = responseData.comments.map(comment => {
return {
id: comment.id,
name: comment.author.name,
date: new Date(comment.date),
text: comment.text,
likes: comment.likes,
isLiked: false,
}
})
return appComments
})
}

fetchComments().then(data => {
updateComments(data);
renderComments()
}).catch(error => {
console.error('Ошибка загрузки комментариев:', error);
alert('Не удалось загрузить комментарии');
})

const updateComments = (newComments) => {
comments = newComments
}

let comments = [];

const postComment = (name, text) => {
return fetch(host + "/comments", {
method: "POST",
body: JSON.stringify({
text: text,
name: name,
}),
})
.then((response) => {
if (!response.ok) {
return response.text().then(text => {
throw new Error(`Ошибка сервера: ${response.status} ${text}`);
});
}
return response.json();
})
}

const nameInput = document.querySelector('.add-form-name');
const textInput = document.querySelector('.add-form-text');
const addButton = document.querySelector('.add-form-button');
const commentsList = document.querySelector('.comments');

let replyingToCommentId = null;

function escapeHtml(unsafe) {
if (!unsafe) return '';
return unsafe
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#039;');
}

function renderComments() {
let commentsHTML = '';

comments.forEach((comment) => {
const formattedDate = comment.date instanceof Date
? comment.date.toLocaleDateString('ru-RU', {
day: '2-digit',
month: '2-digit',
year: '2-digit',
hour: '2-digit',
minute: '2-digit'
})
: comment.date;

commentsHTML += `
<li class="comment" data-id="${comment.id}">
<div class="comment-header">
<div>${escapeHtml(comment.name)}</div>
<div>${formattedDate}</div>
</div>
<div class="comment-body">
<div class="comment-text">
${escapeHtml(comment.text)}
</div>
</div>
<div class="comment-footer">
<div class="likes">
<span class="likes-counter">${comment.likes}</span>
<button class="like-button ${comment.isLiked ? '-active-like' : ''}" data-id="${comment.id}"></button>
</div>
</div>
</li>
`;
});

commentsList.innerHTML = commentsHTML;

document.querySelectorAll('.like-button').forEach((button) => {
button.addEventListener('click', (event) => {
event.stopPropagation();
const commentId = parseInt(event.target.dataset.id);
toggleLike(commentId);
});
});

document.querySelectorAll('.comment').forEach((commentElement) => {
commentElement.addEventListener('click', (event) => {
if (!event.target.closest('.like-button')) {
const commentId = parseInt(commentElement.dataset.id);
replyToComment(commentId);
}
});
});
}

function toggleLike(commentId) {
const comment = comments.find(c => c.id === commentId);

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

renderComments();
}
}

function replyToComment(commentId) {
const comment = comments.find(c => c.id === commentId);

if (comment) {
replyingToCommentId = commentId;

const replyText = `> ${comment.name}:\n> ${comment.text}\n\n`;

nameInput.value = comment.name;
textInput.value = replyText;

textInput.focus();
}
}

async function addNewComment() {
const name = nameInput.value.trim();
let text = textInput.value.trim();

if (!name || !text) {
alert('Пожалуйста, заполните все поля');
return;
}

const originalText = addButton.textContent;
addButton.disabled = true;
addButton.textContent = 'Добавляем...';

try {
await postComment(name, text);

const updatedComments = await fetchComments();
updateComments(updatedComments);
renderComments();

nameInput.value = '';
textInput.value = '';
replyingToCommentId = null;

} catch (error) {
console.error('Ошибка при добавлении комментария:', error);
alert(`Не удалось отправить комментарий: ${error.message}`);
} finally {
addButton.disabled = false;
addButton.textContent = originalText;
}
}

function initApp() {
renderComments();

addButton.addEventListener('click', addNewComment);

nameInput.addEventListener('input', function() {
console.log('Имя изменено:', this.value);
});

textInput.addEventListener('input', function() {
console.log('Комментарий изменен:', this.value);
});

textInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && e.ctrlKey) {
e.preventDefault();
addNewComment();
}
});
}

document.addEventListener('DOMContentLoaded', initApp);

</script>
</html>
3 changes: 3 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { initApp } from './modules/event-handlers.js';

document.addEventListener('DOMContentLoaded', initApp);
Loading