212 lines
12 KiB
PHP
Executable File
212 lines
12 KiB
PHP
Executable File
<?php
|
||
// views/books/edit.php
|
||
include 'views/layouts/header.php';
|
||
?>
|
||
|
||
<div class="container">
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h1 class="h2">Редактирование книги</h1>
|
||
<a href="<?= SITE_URL ?>/books" class="btn btn-outline-secondary">
|
||
<i class="bi bi-arrow-left"></i> Назад к книгам
|
||
</a>
|
||
</div>
|
||
|
||
<?php if (isset($_SESSION['cover_error'])): ?>
|
||
<div class="alert alert-danger">
|
||
Ошибка загрузки обложки: <?= e($_SESSION['cover_error']) ?>
|
||
<?php unset($_SESSION['cover_error']); ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<form method="post" enctype="multipart/form-data" id="book-form">
|
||
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
|
||
|
||
<!-- Аккордеон для основной информации (свернут) -->
|
||
<div class="accordion mb-4" id="bookInfoAccordion">
|
||
<div class="accordion-item">
|
||
<h2 class="accordion-header">
|
||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#bookInfoCollapse">
|
||
<i class="bi bi-info-circle me-2"></i> Основная информация
|
||
</button>
|
||
</h2>
|
||
<div id="bookInfoCollapse" class="accordion-collapse collapse" data-bs-parent="#bookInfoAccordion">
|
||
<div class="accordion-body">
|
||
<div class="mb-3">
|
||
<label for="title" class="form-label">Название книги *</label>
|
||
<input type="text" class="form-control" id="title" name="title"
|
||
value="<?= e($book['title'] ?? '') ?>"
|
||
placeholder="Введите название книги" required>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="genre" class="form-label">Жанр</label>
|
||
<input type="text" class="form-control" id="genre" name="genre"
|
||
value="<?= e($book['genre'] ?? '') ?>"
|
||
placeholder="Например: Фантастика, Роман, Детектив...">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="series_id" class="form-label">Серия</label>
|
||
<select class="form-select" id="series_id" name="series_id">
|
||
<option value="">-- Без серии --</option>
|
||
<?php foreach ($series as $ser): ?>
|
||
<option value="<?= $ser['id'] ?>" <?= ($ser['id'] == ($book['series_id'] ?? 0)) ? 'selected' : '' ?>>
|
||
<?= e($ser['title']) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="sort_order_in_series" class="form-label">Порядок в серии</label>
|
||
<input type="number" class="form-control" id="sort_order_in_series" name="sort_order_in_series"
|
||
value="<?= e($book['sort_order_in_series'] ?? '') ?>"
|
||
placeholder="Номер по порядку в серии" min="1">
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="description" class="form-label">Описание книги</label>
|
||
<textarea class="form-control" id="description" name="description"
|
||
placeholder="Краткое описание сюжета или аннотация..."
|
||
rows="4"><?= e($book['description'] ?? '') ?></textarea>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="cover_image" class="form-label">Обложка книги</label>
|
||
<?php if (!empty($book['cover_image'])): ?>
|
||
<div class="mb-2">
|
||
<img src="<?= COVERS_URL . e($book['cover_image']) ?>"
|
||
alt="Обложка"
|
||
class="img-thumbnail"
|
||
style="max-height: 150px;">
|
||
<div class="form-text">Текущая обложка</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
<input type="file" class="form-control" id="cover_image" name="cover_image"
|
||
accept="image/jpeg,image/png,image/gif,image/webp">
|
||
<div class="form-text">
|
||
Разрешены форматы: JPG, PNG, GIF, WebP. Максимальный размер: 5MB. Оставьте пустым, чтобы оставить текущую обложку.
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-4">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="published" name="published" value="1"
|
||
<?= !empty($book['published']) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="published">
|
||
Опубликовать книгу (показывать на публичной странице автора)
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-4">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="is_short_story" name="is_short_story" value="1"
|
||
<?= !empty($book['is_short_story']) ? 'checked' : '' ?> onchange="toggleStoryEditor()">
|
||
<label class="form-check-label" for="is_short_story">
|
||
Это рассказ (без разбивки на главы)
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Редактор рассказа (всегда видимый) -->
|
||
<div class="mb-4" id="story-editor-card" style="display: <?= !empty($book['is_short_story']) ? 'block' : 'none' ?>">
|
||
<div class="card">
|
||
<div class="card-header bg-success bg-opacity-10">
|
||
<h5 class="card-title mb-0 text-success">
|
||
<i class="bi bi-book me-2"></i>Содержание рассказа
|
||
</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<div id="quill-editor" style="height: 500px;" data-content="<?= htmlspecialchars($book['content'] ?? '', ENT_QUOTES) ?>"></div>
|
||
<textarea name="content" id="content" style="display: none;"><?= htmlspecialchars($book['content'] ?? '', ENT_QUOTES) ?></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Главы книги (всегда видимые) -->
|
||
<div class="mb-4" id="chapters-card" style="display: <?= !empty($book['is_short_story']) ? 'none' : 'block' ?>">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h5 class="card-title mb-0">Главы книги</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<?php if (!empty($chapters)): ?>
|
||
<div class="table-responsive">
|
||
<table class="table table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>Название</th>
|
||
<th>Статус</th>
|
||
<th>Слов</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($chapters as $chapter): ?>
|
||
<tr>
|
||
<td><?= e($chapter['title']) ?></td>
|
||
<td>
|
||
<span class="badge <?= $chapter['status'] == 'published' ? 'bg-success' : 'bg-warning' ?>">
|
||
<?= $chapter['status'] == 'published' ? 'Опубликована' : 'Черновик' ?>
|
||
</span>
|
||
</td>
|
||
<td><?= $chapter['word_count'] ?></td>
|
||
<td>
|
||
<a href="<?= SITE_URL ?>/chapters/<?= $chapter['id'] ?>/edit" class="btn btn-sm btn-outline-primary">
|
||
<i class="bi bi-pencil"></i> Редактировать
|
||
</a>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="text-center py-4">
|
||
<i class="bi bi-file-text fs-1 text-muted"></i>
|
||
<p class="text-muted mt-2">В этой книге пока нет глав</p>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="d-flex gap-2">
|
||
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters" class="btn btn-outline-primary">
|
||
<i class="bi bi-list-ul"></i> Все главы
|
||
</a>
|
||
<a href="<?= SITE_URL ?>/books/<?= $book['id'] ?>/chapters/create" class="btn btn-primary">
|
||
<i class="bi bi-plus-circle"></i> Добавить главу
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Кнопка сохранения -->
|
||
<div class="mb-4">
|
||
<button type="submit" class="btn btn-primary btn-lg">
|
||
<i class="bi bi-check-circle"></i> Сохранить изменения
|
||
</button>
|
||
</div>
|
||
</form>
|
||
|
||
<script src="<?= SITE_URL ?>/assets/js/editor.js"></script>
|
||
<script src="<?= SITE_URL ?>/assets/js/autosave.js"></script>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const checkbox = document.getElementById('is_short_story');
|
||
if (checkbox && checkbox.checked) {
|
||
toggleStoryEditor();
|
||
}
|
||
});
|
||
</script>
|
||
</div>
|