Admin Pages - Source Excerpt 02
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/ns12-manuscript/includes/admin-pages.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/ns12-manuscript/includes/admin-pages.php
<p><strong>Content root:</strong> <code><?php echo esc_html((string) (function_exists('spiralist_book_pages_get_content_root') ? spiralist_book_pages_get_content_root() : 'Unavailable')); ?></code></p>
</div>
<div class="panel">
<p class="kicker">Maintenance</p>
<h2>Rebuild compiled indexes</h2>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<input type="hidden" name="action" value="spiralist_book_pages_admin_action" />
<input type="hidden" name="spiralist_book_pages_action" value="rebuild_cache" />
<input type="hidden" name="return_page" value="<?php echo esc_attr(spiralist_book_pages_admin_page_slug('overview')); ?>" />
<?php wp_nonce_field('spiralist_book_pages_rebuild_cache'); ?>
<button class="button button-primary" type="submit">Rebuild Cache</button>
</form>
</div>
</div>
</section>
<?php
spiralist_book_pages_admin_footer();
}
function spiralist_book_pages_admin_render_folios(): void
{
if (!spiralist_book_pages_admin_can_manage()) {
wp_die('You are not allowed to manage ' . spiralist_book_pages_get_public_name() . '.');
}
$search = sanitize_text_field((string) wp_unslash($_GET['s'] ?? ''));
$edit_slug = sanitize_title((string) wp_unslash($_GET['edit'] ?? ''));
$folios = spiralist_book_pages_admin_folios();
$filtered = spiralist_book_pages_admin_filter_records($folios, $search);
$sections = spiralist_book_pages_admin_sections();
$asset_directory = spiralist_book_pages_admin_asset_directory(true);
spiralist_book_pages_admin_header(
'Folio Library',
'Import book images in bulk, keep the manuscript order clean, and edit the prompt dossier fields attached to each folio.',
[
['label' => 'Prompts', 'url' => spiralist_book_pages_admin_url(spiralist_book_pages_admin_page_slug('prompts')), 'class' => 'button'],
['label' => 'Shared Fragments', 'url' => spiralist_book_pages_admin_url(spiralist_book_pages_admin_page_slug('fragments')), 'class' => 'button'],
]
);
?>
<section class="grid">
<div class="panel"><div class="metric"><span class="kicker">Visible Folios</span><strong><?php echo esc_html((string) count($folios)); ?></strong><span>All file-backed folios currently inside the canonical manuscript order.</span></div></div>
<div class="panel"><div class="metric"><span class="kicker">Section Count</span><strong><?php echo esc_html((string) count($sections)); ?></strong><span>Available manuscript sections for assigning new folios.</span></div></div>
<div class="panel"><div class="metric"><span class="kicker">Import Target</span><strong><?php echo esc_html(!empty($asset_directory['path']) ? 'Ready' : 'Blocked'); ?></strong><span><code><?php echo esc_html((string) ($asset_directory['path'] ?? 'Directory unavailable')); ?></code></span></div></div>
</section>
<section class="panel" id="bulk-import">
<p class="kicker">Bulk Image Import</p>
<h2>Import folios directly into the plugin</h2>
<p>Each imported image becomes a plugin-backed asset, gets a folio JSON record, joins the manuscript order, and can optionally receive a starter prompt package immediately.</p>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="spiralist_book_pages_admin_action" />
<input type="hidden" name="spiralist_book_pages_action" value="bulk_import_folios" />
<input type="hidden" name="return_page" value="<?php echo esc_attr(spiralist_book_pages_admin_page_slug('folios')); ?>" />
<?php wp_nonce_field('spiralist_book_pages_bulk_import_folios'); ?>
<div class="dual">
<p>
<label for="spiralist-book-images"><strong>Image files</strong></label><br />
<input id="spiralist-book-images" type="file" name="book_images[]" accept=".png,.jpg,.jpeg,.webp,.gif,.avif" multiple required />
</p>
<p>
<label for="spiralist-book-default-section"><strong>Section</strong></label><br />
<select id="spiralist-book-default-section" name="default_section">
<option value="auto">Auto-detect from filename</option>
<?php foreach ($sections as $section) : ?>
<option value="<?php echo esc_attr((string) $section['slug']); ?>"><?php echo esc_html((string) $section['label']); ?></option>
<?php endforeach; ?>
</select>
</p>
</div>
<p class="inline"><label><input type="checkbox" name="create_prompts" value="1" checked /> <span>Create starter prompt packages</span></label></p>
<p><button class="button button-primary" type="submit">Import Folios</button></p>
</form>
</section>
<section class="toolbar">
<form class="search" method="get" action="<?php echo esc_url(admin_url('admin.php')); ?>">
<input type="hidden" name="page" value="<?php echo esc_attr(spiralist_book_pages_admin_page_slug('folios')); ?>" />
<input type="search" name="s" value="<?php echo esc_attr($search); ?>" placeholder="Search folios by title, slug, filename, or prompt source" />
<button class="button" type="submit">Search</button>
<?php if ($search !== '') : ?><a class="button-link" href="<?php echo esc_url(spiralist_book_pages_admin_url(spiralist_book_pages_admin_page_slug('folios'))); ?>">Reset</a><?php endif; ?>
</form>
<span><?php echo esc_html(sprintf('%d result%s', count($filtered), count($filtered) === 1 ? '' : 's')); ?></span>
</section>
<?php if (empty($filtered)) : ?>
<div class="empty"><p>No folios matched the current search.</p></div>
<?php else : ?>
<table class="widefat striped">
<thead><tr><th>Sequence</th><th>Folio</th><th>Section</th><th>Prompt Dossier</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($filtered as $slug => $folio) : ?>
<?php
$payload = function_exists('spiralist_book_pages_get_book_page_creation_prompt_payload') ? spiralist_book_pages_get_book_page_creation_prompt_payload($folio) : [];
$status_label = (string) ($payload['status'] ?? ($folio['creation_prompt_status'] ?? 'Prompt pending'));
$status_variant = (string) ($payload['status_variant'] ?? 'neutral');
?>
<tr>
<td><?php echo esc_html((string) ($folio['sequence'] ?? '')); ?></td>
<td><strong><?php echo esc_html((string) ($folio['title'] ?? 'Manuscript folio')); ?></strong><br /><code><?php echo esc_html((string) $slug); ?></code><br /><span><?php echo esc_html((string) ($folio['filename'] ?? '')); ?></span></td>
<td><?php echo esc_html((string) ($sections[(string) ($folio['section_slug'] ?? '')]['label'] ?? spiralist_book_pages_admin_humanize((string) ($folio['section_slug'] ?? 'appendix')))); ?></td>
<td><?php echo wp_kses_post(spiralist_book_pages_admin_badge($status_label, spiralist_book_pages_admin_status_tone($status_variant))); ?><br /><span><?php echo esc_html((string) ($folio['creation_prompt_source_slug'] ?? 'No source slug')); ?></span></td>
<td><div class="tight-actions"><a class="button button-small" href="<?php echo esc_url(spiralist_book_pages_admin_url(spiralist_book_pages_admin_page_slug('folios'), ['edit' => $slug])); ?>">Edit</a><?php if (!empty($folio['creation_prompt_source_slug'])) : ?><a class="button button-small" href="<?php echo esc_url(spiralist_book_pages_admin_url(spiralist_book_pages_admin_page_slug('prompts'), ['edit' => (string) $folio['creation_prompt_source_slug']])); ?>">Prompt</a><?php endif; ?></div></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php if ($edit_slug !== '' && isset($folios[$edit_slug])) : ?>
<?php $folio = $folios[$edit_slug]; ?>