class QuoteApp {
constructor() {
this.quotes = [];
this.author = "Денис Шулепов";
this.serverUrl = window.location.origin;
this.init();
}
init() {
this.bindEvents();
this.loadQuotes();
}
async loadQuotes() {
try {
const response = await fetch(`${this.serverUrl}/api/quotes`);
if (response.ok) {
this.quotes = await response.json();
this.renderQuotes();
} else {
throw new Error("Ошибка загрузки цитат");
}
} catch (error) {
console.error("Ошибка при загрузке цитат:", error);
this.showError("Не удалось загрузить цитаты с сервера");
this.showEmptyState();
}
}
bindEvents() {
// События удалены - только автоматическая публикация
}
showEmptyState() {
const quotesFeed = document.getElementById("quotesFeed");
quotesFeed.innerHTML = `
Добро пожаловать в гейский цитатник!
Ожидаем первую автоматическую публикацию цитаты...
`;
}
renderQuotes() {
const quotesFeed = document.getElementById("quotesFeed");
if (this.quotes.length === 0) {
this.showEmptyState();
return;
}
quotesFeed.innerHTML = this.quotes
.map((quote) => this.createQuoteCard(quote))
.join("");
this.bindQuoteActions();
}
createQuoteCard(quote) {
const date = new Date(quote.date).toLocaleDateString("ru-RU", {
day: "numeric",
month: "long",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
});
return `
${this.escapeHtml(quote.text)}
`;
}
bindQuoteActions() {
// Дополнительные обработчики для карточек цитат
}
async generateNewQuote() {
const loading = document.getElementById("loading");
loading.style.display = "block";
try {
const response = await fetch(`${this.serverUrl}/api/quotes`, {
method: "POST",
});
if (response.ok) {
const newQuote = await response.json();
this.quotes.unshift(newQuote);
this.renderQuotes();
this.showSuccess("Новая цитата создана!");
} else {
throw new Error("Ошибка сервера");
}
} catch (error) {
console.error("Ошибка при генерации цитаты:", error);
this.showError(
"Не удалось сгенерировать цитату. Проверьте подключение к серверу."
);
} finally {
loading.style.display = "none";
}
}
async deleteQuote(id) {
if (confirm("Вы уверены, что хотите удалить эту цитату?")) {
try {
const response = await fetch(`${this.serverUrl}/api/quotes/${id}`, {
method: "DELETE",
});
if (response.ok) {
this.quotes = this.quotes.filter((q) => q.id !== id);
this.renderQuotes();
this.showSuccess("Цитата удалена!");
} else {
throw new Error("Ошибка сервера");
}
} catch (error) {
console.error("Ошибка при удалении цитаты:", error);
this.showError("Не удалось удалить цитату");
}
}
}
copyQuote(id) {
const quote = this.quotes.find((q) => q.id === id);
if (quote) {
const text = `"${quote.text}"\n— ${quote.author}`;
if (navigator.clipboard) {
navigator.clipboard
.writeText(text)
.then(() => {
this.showSuccess("Цитата скопирована в буфер обмена!");
})
.catch(() => {
this.fallbackCopyToClipboard(text);
});
} else {
this.fallbackCopyToClipboard(text);
}
}
}
fallbackCopyToClipboard(text) {
const textArea = document.createElement("textarea");
textArea.value = text;
textArea.style.position = "fixed";
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand("copy");
this.showSuccess("Цитата скопирована в буфер обмена!");
} catch (err) {
console.error("Не удалось скопировать текст:", err);
this.showError("Не удалось скопировать цитату");
}
document.body.removeChild(textArea);
}
showError(message) {
this.showNotification(message, "error");
}
showSuccess(message) {
this.showNotification(message, "success");
}
showNotification(message, type = "info") {
const notification = document.createElement("div");
notification.className = `notification notification-${type}`;
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: ${
type === "error"
? "#e74c3c"
: type === "success"
? "#27ae60"
: "#ff6b9d"
};
color: white;
padding: 15px 20px;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
z-index: 1000;
max-width: 300px;
font-size: 14px;
animation: slideIn 0.3s ease-out;
`;
document.body.appendChild(notification);
setTimeout(() => {
notification.style.animation = "slideOut 0.3s ease-out";
setTimeout(() => {
document.body.removeChild(notification);
}, 300);
}, 3000);
}
escapeHtml(text) {
const div = document.createElement("div");
div.textContent = text;
return div.innerHTML;
}
}
// Добавляем стили для анимаций уведомлений
const style = document.createElement("style");
style.textContent = `
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideOut {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(100%);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// Инициализация приложения
const app = new QuoteApp();