finish line!

This commit is contained in:
2025-11-26 17:25:27 +08:00
parent 833d125f64
commit 14434bc2ac
261 changed files with 4530 additions and 1014 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
<?php include 'views/layouts/header.php'; ?>
<div class="container">
<div class="container" style="margin:0; width: auto;">
<h1>Управление пользователями</h1>
<?php if (isset($_SESSION['success'])): ?>
@@ -29,7 +29,7 @@
<a href="<?= SITE_URL ?>/admin/add-user" role="button">📝 Добавить пользователя</a>
</article>
<?php else: ?>
<div style="overflow-x: auto;">
<div style="overflow-x: auto; width:100%;">
<table class="compact-table">
<thead>
<tr>
+17 -17
View File
@@ -97,14 +97,14 @@ include 'views/layouts/header.php';
<button type="submit" class="contrast">
💾 Сохранить изменения
</button>
<a href="<?= SITE_URL ?>/books" role="button" class="secondary">
<!-- <a href="<?= SITE_URL ?>/books" role="button" class="secondary">
❌ Отмена
</a>
</a> -->
</div>
</form>
<?php if ($book): ?>
<div style="margin-top: 2rem; padding: 1rem; background: var(--card-background-color); border-radius: 5px;">
<div style="margin-top: 0.5rem; padding: 0rem; background: var(--card-background-color); border-radius: 5px;">
<h3>Публичная ссылка для чтения</h3>
<div style="display: flex; gap: 5px; align-items: center; flex-wrap: wrap;">
<input type="text"
@@ -112,12 +112,12 @@ include 'views/layouts/header.php';
value="<?= e(SITE_URL . '/book/' . $book['share_token']) ?>"
readonly
style="flex: 1; padding: 8px; border: 1px solid var(--border-color); border-radius: 4px; background: white;">
<button type="button" onclick="copyShareLink()" class="compact-button secondary">
<button type="button" onclick="copyShareLink()" class="adaptive-button">
📋 Копировать
</button>
<form method="post" action="<?= SITE_URL ?>/books/<?= $book['id'] ?>/regenerate-token" style="display: inline;">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
<button type="submit" class="compact-button secondary" onclick="return confirm('Создать новую ссылку? Старая ссылка перестанет работать.')">
<button type="submit" class="adaptive-button secondary" onclick="return confirm('Создать новую ссылку? Старая ссылка перестанет работать.')">
🔄 Обновить
</button>
</form>
@@ -126,20 +126,20 @@ include 'views/layouts/header.php';
<strong>Примечание:</strong> В публичном просмотре отображаются только главы со статусом "Опубликована"
</p>
</div>
<div style="margin-top: 2rem; padding: 1rem; background: var(--card-background-color); border-radius: 5px;">
<div style="margin-top: 0.5rem; padding: 0rem; background: var(--card-background-color); border-radius: 5px;">
<h3>Экспорт книги</h3>
<p style="margin-bottom: 0.5rem;">Экспортируйте книгу в различные форматы:</p>
<div style="display: flex; gap: 5px; flex-wrap: wrap;">
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/pdf" class="adaptive-button secondary" target="_blank">
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/pdf" class="adaptive-button secondary" target="_blank" role="button">
📄 PDF
</a>
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/docx" class="adaptive-button secondary" target="_blank">
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/docx" class="adaptive-button secondary" target="_blank" role="button">
📝 DOCX
</a>
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/html" class="adaptive-button secondary" target="_blank">
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/html" class="adaptive-button secondary" target="_blank" role="button">
🌐 HTML
</a>
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/txt" class="adaptive-button secondary" target="_blank">
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/txt" class="adaptive-button secondary" target="_blank" role="button">
📄 TXT
</a>
</div>
@@ -147,13 +147,13 @@ include 'views/layouts/header.php';
<strong>Примечание:</strong> Экспортируются все главы книги (включая черновики)
</p>
</div>
<div style="margin-top: 3rem;">
<div style="margin-top: 0.5rem;">
<h2>Главы этой книги</h2>
<div style="display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 1rem;">
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters" class="adaptive-button secondary">
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters" class="adaptive-button secondary" role="button">
📑 Все главы
</a>
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters/create" class="adaptive-button secondary">
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters/create" class="adaptive-button secondary" role="button">
✏️ Добавить главу
</a>
</div>
@@ -189,18 +189,18 @@ include 'views/layouts/header.php';
</table>
</div>
<?php else: ?>
<div style="text-align: center; padding: 2rem; background: var(--card-background-color); border-radius: 5px;">
<div style="text-align: center; padding: 0.5rem; background: var(--card-background-color); border-radius: 5px;">
<p style="margin-bottom: 1rem;">В этой книге пока нет глав.</p>
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters/create" class="adaptive-button secondary">
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters/create" class="adaptive-button secondary" role="button">
✏️ Добавить первую главу
</a>
</div>
<?php endif; ?>
</div>
<div style="margin-top: 2rem; text-align: center;">
<div style="margin-top: 0.5rem; text-align: center;">
<form method="post" action="<?= SITE_URL ?>/books/<?= $book['id'] ?>/delete" style="display: inline;" onsubmit="return confirm('Вы уверены, что хотите удалить книгу «<?= e($book['title']) ?>»? Все главы также будут удалены.');">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
<button type="submit" class="button" style="background: #ff4444; border-color: #ff4444; color: white;">
<button type="submit" class="adaptive-button red-btn">
🗑️ Удалить книгу
</button>
</form>
+3 -3
View File
@@ -6,8 +6,8 @@ include 'views/layouts/header.php';
<h1>Мои книги <small style="color: #ccc; font-size:1rem;">(Всего книг: <?= count($books) ?>)</small></h1>
<div style="display: flex; justify-content: right; align-items: center; margin-bottom: 1rem; flex-wrap: wrap; gap: 1rem;">
<a href="<?= SITE_URL ?>/books/create" class="action-button primary"> Новая книга</a>
<div style="display: flex; justify-content: left; margin-bottom: 1rem; flex-wrap: wrap; gap: 1rem;">
<a href="<?= SITE_URL ?>/books/create" class="action-button primary" role="button">➕ Новая книга</a>
<?php if (!empty($books)): ?>
<a href="#" onclick="showDeleteAllConfirmation()" class="action-button delete">🗑️ Удалить все книги</a>
<?php endif; ?>
@@ -81,7 +81,7 @@ include 'views/layouts/header.php';
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters" class="compact-button secondary-btn">
📑 Главы
</a>
<a href="<?= SITE_URL ?>/book/<?= $book['share_token'] ?>" class="compact-button secondary-btn" target="_blank">
<a href="<?= SITE_URL ?>/book/<?= $book['share_token'] ?>" class="compact-button green-btn" target="_blank">
👁️ Просмотр
</a>
</div>
+43 -32
View File
@@ -3,8 +3,8 @@
include 'views/layouts/header.php';
?>
<div class="container">
<article style="max-width: 800px; margin: 0 auto;">
<div class="container" style="padding: 0em; margin: 0em auto; width: 90%;">
<article style="margin: 0 auto;">
<header style="text-align: center; margin-bottom: 2rem;">
<?php if (!empty($book['cover_image'])): ?>
<div style="margin-bottom: 1rem;">
@@ -18,7 +18,7 @@ include 'views/layouts/header.php';
<h1 style="margin-bottom: 0.5rem;"><?= e($book['title']) ?></h1>
<p style="color: #666; font-style: italic; margin-bottom: 0.5rem;">
Автор: <a href="<?= SITE_URL ?>/author/<?= $book['user_id'] ?>"><?= e($author_name) ?></a>
Автор: <a href="<?= SITE_URL ?>/author/<?= $book['user_id'] ?>"><?= e($author['display_name']??$author['username']) ?></a>
</p>
<?php if (!empty($book['genre'])): ?>
@@ -33,12 +33,43 @@ include 'views/layouts/header.php';
</div>
<?php endif; ?>
<div style="display: flex; justify-content: center; gap: 1rem; flex-wrap: wrap; font-size: 0.9em; color: #666;">
<div style="display: block; justify-content: center; gap: 1rem; flex-wrap: wrap; font-size: 0.9em; color: #666;">
<span>Глав: <?= count($chapters) ?></span>
<span>Слов: <?= array_sum(array_column($chapters, 'word_count')) ?></span>
<a href="<?= SITE_URL ?>/export/shared/<?= $book['share_token'] ?>" class="adaptive-button secondary" style="font-size: 0.8em;">
📄 Скачать книгу
</a>
<p>
<?php if (!is_logged_in()): ?>
<div style="display: flex; gap: 5px; flex-wrap: wrap; justify-content: center;">
<a href="<?= SITE_URL ?>/export/shared/<?= $book['share_token'] ?>/pdf" class="adaptive-button secondary" target="_blank" role="button">
📄 PDF
</a>
<a href="<?= SITE_URL ?>/export/shared/<?= $book['share_token'] ?>/docx" class="adaptive-button secondary" target="_blank" role="button">
📝 DOCX
</a>
<a href="<?= SITE_URL ?>/export/shared/<?= $book['share_token'] ?>/html" class="adaptive-button secondary" target="_blank" role="button">
🌐 HTML
</a>
<a href="<?= SITE_URL ?>/export/shared/<?= $book['share_token'] ?>/txt" class="adaptive-button secondary" target="_blank" role="button">
📄 TXT
</a>
</div>
<?php endif; ?>
<?php if (is_logged_in()): ?>
<div style="display: flex; gap: 5px; flex-wrap: wrap; justify-content: center;">
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/pdf" class="adaptive-button secondary" target="_blank" role="button">
📄 PDF
</a>
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/docx" class="adaptive-button secondary" target="_blank" role="button">
📝 DOCX
</a>
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/html" class="adaptive-button secondary" target="_blank" role="button">
🌐 HTML
</a>
<a href="<?= SITE_URL ?>/export/<?= $book['id'] ?>/txt" class="adaptive-button secondary" target="_blank" role="button">
📄 TXT
</a>
</div>
<?php endif; ?>
</p>
</div>
</header>
@@ -48,23 +79,15 @@ include 'views/layouts/header.php';
<p>Автор еще не опубликовал содержание книги</p>
</div>
<?php else: ?>
<h2 style="text-align: center; margin-bottom: 2rem;">Оглавление</h2>
<h3 style="text-align: center; margin-bottom: 2rem; margin-top: 0em;">Оглавление</h3>
<div class="chapters-list">
<?php foreach ($chapters as $index => $chapter): ?>
<article style="margin-bottom: 1rem; padding: 1rem; background: var(--card-background-color); border-radius: 8px;">
<h3 style="margin-top: 0;">
<h6 style="margin-top: 0; margin-bottom: 0em;">
<a href="#chapter-<?= $chapter['id'] ?>" style="text-decoration: none;">
Глава <?= $index + 1 ?>: <?= e($chapter['title']) ?>
</a>
</h3>
<div style="display: flex; gap: 10px; align-items: center;">
<small style="color: var(--muted-color);">
Слов: <?= $chapter['word_count'] ?>
| Обновлено: <?= date('d.m.Y', strtotime($chapter['updated_at'])) ?>
</small>
</div>
</article>
</h6>
<?php endforeach; ?>
</div>
@@ -77,20 +100,8 @@ include 'views/layouts/header.php';
</h2>
<div style="margin-top: 1.5rem; line-height: 1.6;">
<?php if ($book['editor_type'] == 'markdown'): ?>
<?= $Parsedown->text($chapter['content']) ?>
<?php else: ?>
<?= $chapter['content'] ?>
<?php endif; ?>
<?= $chapter['content'] ?>
</div>
<?php if ($index < count($chapters) - 1): ?>
<div style="text-align: center; margin-top: 2rem;">
<a href="#chapter-<?= $chapters[$index + 1]['id'] ?>" class="button">
📖 Следующая глава
</a>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
+23 -32
View File
@@ -1,5 +1,4 @@
<?php
// views/chapters/create.php
include 'views/layouts/header.php';
?>
@@ -13,7 +12,7 @@ include 'views/layouts/header.php';
<form method="post" id="chapter-form">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
<div style="margin-bottom: 1rem;">
<label for="title" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
Название главы *
@@ -23,14 +22,19 @@ include 'views/layouts/header.php';
placeholder="Введите название главы"
style="width: 100%; margin-bottom: 1.5rem;"
required>
<label for="content" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
Содержание главы *
</label>
<textarea id="content" name="content" class="writer-editor" style="display: none;">
<?= e($_POST['content'] ?? '') ?>
</textarea>
<!-- Контейнер Quill -->
<div id="quill-editor"
class="writer-editor-container"
style="height:500px;"
data-content="<?= htmlspecialchars($_POST['content'] ?? '', ENT_QUOTES) ?>">
</div>
<!-- Скрытый textarea для формы -->
<textarea id="content" name="content" style="display:none;"><?= e($_POST['content'] ?? '') ?></textarea>
<div style="margin-top: 1rem;">
<label for="status" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
Статус главы
@@ -44,63 +48,50 @@ include 'views/layouts/header.php';
</small>
</div>
</div>
<div style="display: flex; gap: 10px; flex-wrap: wrap; margin-top: 1.5rem;">
<button type="submit" class="contrast">
💾 Сохранить главу
</button>
<button type="button" onclick="previewChapter()" class="secondary">
👁️ Предпросмотр
</button>
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters" role="button" class="secondary">
❌ Отмена
</a>
<button type="submit" class="contrast">💾 Сохранить главу</button>
<button type="button" onclick="previewChapter()" class="secondary">👁️ Предпросмотр</button>
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters" role="button" class="secondary">❌ Отмена</a>
</div>
</form>
<link href="/assets/css/quill_reset.css" rel="stylesheet">
<script>
function previewChapter() {
const form = document.getElementById('chapter-form');
const formData = new FormData(form);
// Создаем временную форму для предпросмотра
const tempForm = document.createElement('form');
tempForm.method = 'POST';
tempForm.action = '<?= SITE_URL ?>/chapters/preview';
tempForm.target = '_blank';
tempForm.style.display = 'none';
// Добавляем CSRF токен
const csrfInput = document.createElement('input');
csrfInput.name = 'csrf_token';
csrfInput.value = '<?= generate_csrf_token() ?>';
tempForm.appendChild(csrfInput);
// Добавляем контент
const contentInput = document.createElement('input');
contentInput.name = 'content';
contentInput.value = document.getElementById('content').value;
tempForm.appendChild(contentInput);
// Добавляем заголовок
const titleInput = document.createElement('input');
titleInput.name = 'title';
titleInput.value = document.getElementById('title').value || 'Предпросмотр главы';
tempForm.appendChild(titleInput);
// Добавляем тип редактора
const editorTypeInput = document.createElement('input');
editorTypeInput.name = 'editor_type';
editorTypeInput.value = '<?= $book['editor_type'] ?? 'markdown' ?>';
tempForm.appendChild(editorTypeInput);
document.body.appendChild(tempForm);
tempForm.submit();
document.body.removeChild(tempForm);
}
</script>
<script src="/assets/js/editor.js"></script>
<script src="/assets/js/autosave.js"></script>
<?php include 'views/layouts/footer.php'; ?>
<?php include 'views/layouts/footer.php'; ?>
+9 -3
View File
@@ -27,9 +27,15 @@ include 'views/layouts/header.php';
<label for="content" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
Содержание главы *
</label>
<textarea id="content" name="content" class="writer-editor" style="display: none;">
<?= e($chapter['content'] ?? '') ?>
</textarea>
<!-- Контейнер Quill -->
<div id="quill-editor"
class="writer-editor-container"
style="height:500px;"
data-content="<?= htmlspecialchars($chapter['content'] ?? '', ENT_QUOTES) ?>">
</div>
<!-- Скрытый textarea для формы -->
<textarea id="content" name="content" style="display:none;"></textarea>
<div style="margin-top: 1rem;">
+8 -8
View File
@@ -5,11 +5,11 @@ include 'views/layouts/header.php';
<div style="margin-bottom: 1rem;">
<h1 style="margin: 0 0 0.5rem 0; font-size: 1.5rem;">Главы книги: <?= e($book['title']) ?></h1>
<div style="display: flex; gap: 5px; flex-wrap: wrap;">
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters/create" class="adaptive-button"> Новая глава</a>
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/edit" class="adaptive-button secondary">✏️ Редактировать книгу</a>
<a href="<?= SITE_URL ?>/book/<?= $book['share_token'] ?>" class="adaptive-button secondary" target="_blank">👁️ Просмотреть книгу</a>
<a href="<?= SITE_URL ?>/books" class="adaptive-button secondary">📚 Все книги</a>
<div style="display: flex; gap: 5px; flex-wrap: wrap; justify-content:center;">
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters/create" class="adaptive-button" role="button">➕ Новая глава</a>
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/edit" class="adaptive-button secondary" role="button">✏️ Редактировать книгу</a>
<a href="<?= SITE_URL ?>/book/<?= $book['share_token'] ?>" class="adaptive-button green-btn" role="button" target="_blank">👁️ Публичный доступ</a>
<a href="<?= SITE_URL ?>/book/all/<?= $book['id'] ?>" class="adaptive-button" role="button" target="_blank">👁️ Полный обзор</a>
</div>
</div>
@@ -38,8 +38,8 @@ include 'views/layouts/header.php';
<td><?= $index + 1 ?></td>
<td>
<strong><?= e($chapter['title']) ?></strong>
<?php if ($chapter['description']): ?>
<br><small style="color: var(--muted-color);"><?= e(mb_strimwidth($chapter['description'], 0, 100, '...')) ?></small>
<?php if ($chapter['content']): ?>
<br><small style="color: var(--muted-color);"><?= e(mb_strimwidth($chapter['content'], 0, 100, '...')) ?></small>
<?php endif; ?>
</td>
<td>
@@ -53,7 +53,7 @@ include 'views/layouts/header.php';
</td>
<td>
<div style="display: flex; gap: 3px; flex-wrap: wrap;">
<a href="<?= SITE_URL ?>/chapters/<?= $chapter['id'] ?>/edit" class="compact-button secondary" title="Редактировать">
<a href="<?= SITE_URL ?>/chapters/<?= $chapter['id'] ?>/edit" class="compact-button secondary" title="Редактировать" role="button">
✏️
</a>
<form method="post" action="<?= SITE_URL ?>/chapters/<?= $chapter['id'] ?>/delete" style="display: inline;" onsubmit="return confirm('Вы уверены, что хотите удалить эту главу? Это действие нельзя отменить.');">
+6 -3
View File
@@ -44,14 +44,17 @@ include 'views/layouts/header.php';
<h2>Недавние книги</h2>
<?php if (!empty($recent_books)): ?>
<?php foreach ($recent_books as $book): ?>
<article>
<h3 style="margin-bottom: 0.5rem;">
<article style="margin-bottom: 1em; padding-top: 0.5em;">
<h3 style="margin-bottom: 0.5rem; margin-top: 0.5em;">
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/edit">
<?= e($book['title']) ?>
</a>
</h3>
<?php if ($book['genre']): ?>
<p style="margin: 0; color: var(--muted-color);"><em><?= e($book['genre']) ?></em></p>
<p style="margin: 0; color: var(--muted-color); font-size:small;"><em><?= e($book['genre']) ?></em></p>
<?php endif; ?>
<?php if ($book['description']): ?>
<p style="margin: 0; color: var(--muted-color);"><?= e($book['description']) ?></p>
<?php endif; ?>
<footer>
<small>
+2 -2
View File
@@ -9,8 +9,8 @@
<title><?= e($page_title ?? 'Web Writer') ?></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1.5.10/css/pico.min.css">
<link rel="stylesheet" href="<?= SITE_URL ?>/assets/css/style.css">
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<script src="https://cdn.quilljs.com/1.3.6/quill.min.js"></script>
<link href="<?= SITE_URL ?>/assets/css/quill.snow.css" rel="stylesheet">
<script src="<?= SITE_URL ?>/assets/js/quill.js"></script>
</head>
<body>
<nav class="container-fluid">
+9 -34
View File
@@ -3,10 +3,7 @@ include 'views/layouts/header.php';
?>
<h1>Редактирование серии: <?= e($series['title']) ?></h1>
<div class="grid">
<div>
<article>
<article>
<h2>Основная информация</h2>
<form method="post" action="/series/<?= $series['id'] ?>/edit">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
@@ -23,18 +20,16 @@ include 'views/layouts/header.php';
<button type="submit" class="primary-btn">Сохранить изменения</button>
</form>
</article>
</article>
<div class="grid">
<div>
<article>
<h2>Добавить книгу в серию</h2>
<?php
$available_books = $bookModel->getBooksNotInSeries($_SESSION['user_id'], $series['id']);
?>
<?php if (!empty($available_books)): ?>
<form method="post" action="/series/<?= $series['id'] ?>/add-book">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
<label for="book_id">
Выберите книгу
<select id="book_id" name="book_id" required>
@@ -44,17 +39,15 @@ include 'views/layouts/header.php';
<?php endforeach; ?>
</select>
</label>
<label for="sort_order">
Порядковый номер в серии
<input type="number" id="sort_order" name="sort_order" value="<?= count($books_in_series) + 1 ?>" min="1">
</label>
<button type="submit" class="secondary-btn">Добавить в серию</button>
</form>
<?php else: ?>
<p>Все ваши книги уже добавлены в эту серию или у вас нет доступных книг.</p>
<a href="/books/create" class="primary-btn">Создать новую книгу</a>
<a href="/books/create" class="primary-btn" role="button">Создать новую книгу</a>
<?php endif; ?>
</article>
</div>
@@ -76,12 +69,12 @@ include 'views/layouts/header.php';
<strong><?= e($book['title']) ?></strong>
<small>Порядок: <?= $book['sort_order_in_series'] ?></small>
</div>
<div class="book-actions">
<a href="/books/<?= $book['id'] ?>/edit" class="compact-button">Редактировать</a>
<div class="book-actions" style="display: grid; min-width: 2rem; margin-top: 1rem;">
<a href="/books/<?= $book['id'] ?>/edit" class="compact-button" role="button" style="margin-top: 0em;">✏️</a>
<form method="post" action="/series/<?= $series['id'] ?>/remove-book/<?= $book['id'] ?>"
style="display: inline;" onsubmit="return confirm('Удалить книгу из серии?')">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
<button type="submit" class="compact-button delete-btn">Удалить</button>
<button type="submit" class="compact-button red-btn" style="margin-top: 0em;">🗑️</button>
</form>
</div>
<input type="hidden" name="order[]" value="<?= $book['id'] ?>">
@@ -98,24 +91,6 @@ include 'views/layouts/header.php';
<p>В этой серии пока нет книг. Добавьте книги с помощью формы слева.</p>
<?php endif; ?>
</article>
<article>
<h2>Статистика серии</h2>
<div class="stats-list">
<p><strong>Количество книг:</strong> <?= count($books_in_series) ?></p>
<?php
$total_words = 0;
$total_chapters = 0;
foreach ($books_in_series as $book) {
$stats = $bookModel->getBookStats($book['id']);
$total_words += $stats['total_words'] ?? 0;
$total_chapters += $stats['chapter_count'] ?? 0;
}
?>
<p><strong>Всего глав:</strong> <?= $total_chapters ?></p>
<p><strong>Всего слов:</strong> <?= $total_words ?></p>
</div>
</article>
</div>
</div>
Regular → Executable
+7 -8
View File
@@ -2,9 +2,9 @@
include 'views/layouts/header.php';
?>
<div style="display: flex; justify-content: between; align-items: center; margin-bottom: 2rem; flex-wrap: wrap; gap: 1rem;">
<div style="display: block; justify-content: between; align-items: center; margin-bottom: 2rem; flex-wrap: wrap; gap: 1rem;">
<h1 style="margin: 0;">Мои серии книг</h1>
<a href="/series/create" class="action-button primary"> Создать серию</a>
<a href="/series/create" class="action-button primary" role="button">➕ Создать серию</a>
</div>
<?php if (empty($series)): ?>
@@ -15,7 +15,7 @@ include 'views/layouts/header.php';
Создайте свою первую серию, чтобы организовать книги в циклы и сериалы.
</p>
<div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
<a href="/series/create" class="action-button primary">Создать серию</a>
<a href="/series/create" class="action-button primary" role="button">Создать серию</a>
<a href="/books" class="action-button secondary">Перейти к книгам</a>
</div>
</article>
@@ -61,18 +61,17 @@ include 'views/layouts/header.php';
</div>
</div>
<div class="series-actions">
<a href="/series/<?= $ser['id'] ?>/edit" class="compact-button primary-btn">
<div class="series-actions" style="display:grid;">
<a href="/series/<?= $ser['id'] ?>/edit" class="compact-button primary-btn" role="button">
✏️ Управление
</a>
<a href="/series/<?= $ser['id'] ?>/view" class="compact-button secondary-btn" target="_blank">
<a href="/series/<?= $ser['id'] ?>/view" class="compact-button secondary-btn" target="_blank" role="button">
👁️ Публично
</a>
<form method="post" action="/series/<?= $ser['id'] ?>/delete"
style="display: inline;"
onsubmit="return confirm('Удалить серию? Книги останутся, но будут удалены из серии.')">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
<button type="submit" class="compact-button delete-btn">🗑️</button>
<button type="submit" class="compact-button red-btn">🗑️ Удалить</button>
</form>
</div>
</article>
+2 -2
View File
@@ -3,8 +3,8 @@
include 'views/layouts/header.php';
?>
<div class="container">
<article style="max-width: 800px; margin: 0 auto;">
<div class="container" style="width:100%; margin-left: 0em; margin-right: 0em auto;">
<article>
<header style="text-align: center; margin-bottom: 2rem; border-bottom: 2px solid var(--muted-border-color); padding-bottom: 1rem;">
<!-- Аватарка автора -->
<div style="margin-bottom: 1rem;">