WebOrbiton
v1.0.0.1

StocketBase

122 lines · 5.5 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. if (count(get_included_files()) === 1) {
  6. http_response_code(403);
  7. exit;
  8. }
  9. ​
  10. if (!Auth::hasRoleAtLeast(Auth::ROLE_STORE_MANAGER)) {
  11. echo '<p>You don\'t have access to pages.</p>';
  12. return;
  13. }
  14. ​
  15. $db = Database::site();
  16. ​
  17. try {
  18. SiteFront::homePage();
  19. } catch (Throwable $exception) {
  20. }
  21. ​
  22. $pageId = (int) ($_GET['page_id'] ?? 0) ?: null;
  23. $editingPage = null;
  24. $showForm = $pageId !== null || isset($_GET['new']);
  25. ​
  26. if ($pageId !== null) {
  27. $statement = $db->prepare('SELECT * FROM pages WHERE id = :id LIMIT 1');
  28. $statement->execute(['id' => $pageId]);
  29. $editingPage = $statement->fetch() ?: null;
  30. }
  31. ​
  32. $pages = $db->query('SELECT * FROM pages ORDER BY is_home DESC, sort_order ASC, title ASC')->fetchAll();
  33. $isHomeEditing = $editingPage !== null && (int) ($editingPage['is_home'] ?? 0) === 1;
  34. $blocksJson = $editingPage['content_blocks'] ?? '{"blocks":[]}';
  35. if ($isHomeEditing) {
  36. $blocksJson = BlockEditor::sanitize((string) $blocksJson, false, true);
  37. }
  38. ​
  39. ?>
  40. <div class="dash-header-row">
  41. <h1 class="dash-title"><?= Icons::icon("pages", "icon icon-lg") ?>Pages</h1>
  42. <?php if (!$showForm): ?>
  43. <a href="dashboard.php?view=pages&new=1" class="dash-btn dash-btn-primary"><?= Icons::icon('plus', 'icon icon-sm') ?>New page</a>
  44. <?php endif; ?>
  45. </div>
  46. ​
  47. <table class="dash-table">
  48. <thead><tr><th><?= Icons::icon('heading', 'icon icon-sm') ?>Title</th><th><?= Icons::icon('flag', 'icon icon-sm') ?>Status</th><th><?= Icons::icon('menu', 'icon icon-sm') ?>In menu</th><th></th></tr></thead>
  49. <tbody>
  50. <?php foreach ($pages as $page): ?>
  51. <?php $isHomeRow = (int) ($page['is_home'] ?? 0) === 1; ?>
  52. <tr<?= $isHomeRow ? ' class="page-row-home"' : '' ?>>
  53. <td><?php if ($isHomeRow): ?><?= Icons::icon('home', 'icon icon-sm') ?> <?php endif; ?><?= htmlspecialchars($page['title']) ?><?php if ($isHomeRow): ?> <span class="status-pill status-published">Home page</span><?php endif; ?></td>
  54. <td><span class="status-pill status-<?= htmlspecialchars($page['status']) ?>"><?= htmlspecialchars(StatusLabel::get((string) $page['status'])) ?></span></td>
  55. <td><?= $isHomeRow ? 'Always' : ($page['show_in_menu'] ? 'Yes' : 'No') ?></td>
  56. <td class="dash-table-actions">
  57. <a href="dashboard.php?view=pages&page_id=<?= (int) $page['id'] ?>" class="dash-btn-small"><?= Icons::icon('edit', 'icon icon-sm') ?><?= $isHomeRow ? 'Design' : 'Edit' ?></a>
  58. <?php if (Languages::enabled()): ?>
  59. <a href="translate.php?type=page&id=<?= (int) $page['id'] ?>" class="dash-btn-small"><?= Icons::icon('translate', 'icon icon-sm') ?>Translate</a>
  60. <?php endif; ?>
  61. <?php if (!$isHomeRow): ?>
  62. <form method="post" style="display:inline;" onsubmit="return confirm('Delete this page? This can\'t be undone.');">
  63. <?= Csrf::field() ?>
  64. <input type="hidden" name="action" value="delete_page">
  65. <input type="hidden" name="page_id" value="<?= (int) $page['id'] ?>">
  66. <button type="submit" class="dash-btn-small dash-btn-danger"><?= Icons::icon('trash', 'icon icon-sm') ?>Delete</button>
  67. </form>
  68. <?php endif; ?>
  69. </td>
  70. </tr>
  71. <?php endforeach; ?>
  72. <?php if (empty($pages)): ?>
  73. <tr><td colspan="4">No pages yet. Add one for things like About us or Shipping info.</td></tr>
  74. <?php endif; ?>
  75. </tbody>
  76. </table>
  77. ​
  78. <?php if ($showForm): ?>
  79. <div class="sidebar-box" style="margin-top:20px;">
  80. <h2 class="dash-subtitle" style="margin-top:0;"><?= Icons::icon($isHomeEditing ? 'home' : 'pages', 'icon icon-sm') ?><?= $isHomeEditing ? 'Design home page' : ($editingPage ? 'Edit page' : 'New page') ?></h2>
  81. <?php if ($isHomeEditing): ?>
  82. <p style="color:var(--muted);margin:0 0 14px;">This is your store's front page. <strong>Featured products</strong> and <strong>Product list</strong> always stay on it. You can move them up or down, and add anything you like around them. The title is only for you, customers won't see it.</p>
  83. <?php endif; ?>
  84. ​
  85. <form method="post" id="page-form">
  86. <?= Csrf::field() ?>
  87. <input type="hidden" name="action" value="save_page">
  88. <?php if ($editingPage): ?>
  89. <input type="hidden" name="page_id" value="<?= (int) $editingPage['id'] ?>">
  90. <?php endif; ?>
  91. <input type="hidden" name="blocks_json" id="blocks_json_input">
  92. ​
  93. <label><?= Icons::icon('heading', 'icon icon-sm') ?>Title</label>
  94. <input type="text" name="title" value="<?= htmlspecialchars($editingPage['title'] ?? '') ?>" required>
  95. ​
  96. <label><?= Icons::icon('quote', 'icon icon-sm') ?>Content</label>
  97. <?php if ($isHomeEditing): ?>
  98. <div id="block-editor-root" data-initial-blocks='<?= htmlspecialchars($blocksJson, ENT_QUOTES) ?>' data-home="1"></div>
  99. <?php else: ?>
  100. <div id="block-editor-root" data-initial-blocks='<?= htmlspecialchars($blocksJson, ENT_QUOTES) ?>'<?= (SiteFront::settings()['contact_enabled'] ?? '0') === '1' ? ' data-allow-contact="1"' : '' ?>></div>
  101. ​
  102. <label><input type="checkbox" name="show_in_menu" <?= !empty($editingPage['show_in_menu']) ? 'checked' : '' ?>> Show in the store menu</label>
  103. ​
  104. <label><?= Icons::icon('flag', 'icon icon-sm') ?>Status</label>
  105. <select name="status">
  106. <option value="draft" <?= ($editingPage['status'] ?? 'draft') === 'draft' ? 'selected' : '' ?>>Draft</option>
  107. <option value="published" <?= ($editingPage['status'] ?? '') === 'published' ? 'selected' : '' ?>>Live</option>
  108. </select>
  109. <?php endif; ?>
  110. ​
  111. <div class="publish-actions">
  112. <button type="submit" class="dash-btn dash-btn-primary"><?= Icons::icon('check', 'icon icon-sm') ?>Save page</button>
  113. <a href="dashboard.php?view=pages" class="dash-btn"><?= Icons::icon('x', 'icon icon-sm') ?>Cancel</a>
  114. </div>
  115. </form>
  116. </div>
  117. ​
  118. <?= Asset::js('assets/block-editor.js') ?>
  119. <?php require_once __DIR__ . '/../includes/ai.php'; ?>
  120. <?= Ai::widgetMarkup() ?>
  121. <?php endif; ?>
  122. ​