activities.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. require_once __DIR__ . '/auth.php';
  3. require_once __DIR__ . '/layout.php';
  4. require_admin();
  5. $pdo = get_pdo();
  6. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  7. require_csrf();
  8. $action = $_POST['action'] ?? '';
  9. if ($action === 'add') {
  10. $name = trim($_POST['activityName'] ?? '');
  11. $gid = (int)$_POST['groupID'];
  12. $order = (int)($_POST['sortOrder'] ?? 0);
  13. $hidden = isset($_POST['hidden']) ? 1 : 0;
  14. if ($name !== '' && $gid > 0) {
  15. $pdo->prepare("INSERT INTO activities (groupID,activityName,sortOrder,hidden) VALUES (?,?,?,?)")
  16. ->execute([$gid, $name, $order, $hidden]);
  17. flash('success', "Activity '$name' added.");
  18. } else {
  19. flash('error', 'Please fill all fields.');
  20. }
  21. }
  22. if ($action === 'edit') {
  23. $id = (int)$_POST['activityID'];
  24. $name = trim($_POST['activityName'] ?? '');
  25. $gid = (int)$_POST['groupID'];
  26. $order = (int)($_POST['sortOrder'] ?? 0);
  27. $hidden = isset($_POST['hidden']) ? 1 : 0;
  28. if ($name !== '') {
  29. $pdo->prepare("UPDATE activities SET activityName=?,groupID=?,sortOrder=?,hidden=? WHERE activityID=?")
  30. ->execute([$name, $gid, $order, $hidden, $id]);
  31. flash('success', 'Activity updated.');
  32. } else {
  33. flash('error', 'Name cannot be empty.');
  34. }
  35. }
  36. if ($action === 'delete') {
  37. $id = (int)$_POST['activityID'];
  38. $pdo->prepare("DELETE FROM activities WHERE activityID=?")->execute([$id]);
  39. flash('success', 'Activity deleted.');
  40. }
  41. header('Location: activities.php');
  42. exit;
  43. }
  44. $groups = $pdo->query("SELECT * FROM activity_groups ORDER BY sortOrder,groupID")->fetchAll();
  45. $activities = $pdo->query("
  46. SELECT a.*, ag.groupName
  47. FROM activities a
  48. JOIN activity_groups ag ON ag.groupID = a.groupID
  49. ORDER BY ag.sortOrder, a.sortOrder, a.activityID
  50. ")->fetchAll();
  51. admin_head('Activities', 'activities.php');
  52. show_alerts();
  53. ?>
  54. <h1>Activities</h1>
  55. <div class="card">
  56. <h2>Add New Activity</h2>
  57. <form method="POST">
  58. <?= csrf_field() ?>
  59. <input type="hidden" name="action" value="add">
  60. <div class="form-row">
  61. <div>
  62. <label>Activity Name</label>
  63. <input type="text" name="activityName" placeholder="e.g. Kayaking" required>
  64. </div>
  65. <div>
  66. <label>Group</label>
  67. <select name="groupID" required>
  68. <option value="">– select –</option>
  69. <?php foreach ($groups as $g): ?>
  70. <option value="<?= $g['groupID'] ?>"><?= htmlspecialchars($g['groupName']) ?></option>
  71. <?php endforeach; ?>
  72. </select>
  73. </div>
  74. </div>
  75. <div>
  76. <label>Sort Order</label>
  77. <input type="number" name="sortOrder" value="0" min="0" style="max-width:120px;">
  78. </div>
  79. <label class="check-label"><input type="checkbox" name="hidden" value="1"> Hidden (easter egg, revealed by clicking "Pack it!" 10&times; fast with nothing selected)</label>
  80. <div style="display:flex;gap:.5rem;margin-top:.25rem;">
  81. <button type="submit" class="btn btn-primary">➕ Add</button>
  82. </div>
  83. </form>
  84. </div>
  85. <?php foreach ($activities as $a): ?>
  86. <form id="edit-form-<?= $a['activityID'] ?>" method="POST">
  87. <?= csrf_field() ?>
  88. <input type="hidden" name="action" value="edit">
  89. <input type="hidden" name="activityID" value="<?= $a['activityID'] ?>">
  90. </form>
  91. <?php endforeach; ?>
  92. <table class="tbl tbl-fixed">
  93. <colgroup>
  94. <col style="width:60px">
  95. <col>
  96. <col style="width:180px">
  97. <col style="width:100px">
  98. <col style="width:90px">
  99. <col style="width:200px">
  100. </colgroup>
  101. <thead><tr><th>#</th><th>Name</th><th>Group</th><th>Sort</th><th>Hidden</th><th></th></tr></thead>
  102. <tbody>
  103. <?php foreach ($activities as $a):
  104. $id = $a['activityID'];
  105. ?>
  106. <tr id="row-<?= $id ?>" data-editing="false">
  107. <td style="color:var(--muted)"><?= $id ?></td>
  108. <td>
  109. <div class="view"><?= htmlspecialchars($a['activityName']) ?></div>
  110. <div class="edit"><input type="text" name="activityName" form="edit-form-<?= $id ?>" value="<?= htmlspecialchars($a['activityName']) ?>" required></div>
  111. </td>
  112. <td>
  113. <div class="view"><span class="badge badge-group"><?= htmlspecialchars($a['groupName']) ?></span></div>
  114. <div class="edit">
  115. <select name="groupID" form="edit-form-<?= $id ?>" required>
  116. <?php foreach ($groups as $g): ?>
  117. <option value="<?= $g['groupID'] ?>" <?= $a['groupID'] == $g['groupID'] ? 'selected' : '' ?>><?= htmlspecialchars($g['groupName']) ?></option>
  118. <?php endforeach; ?>
  119. </select>
  120. </div>
  121. </td>
  122. <td>
  123. <div class="view"><?= $a['sortOrder'] ?></div>
  124. <div class="edit"><input type="number" name="sortOrder" form="edit-form-<?= $id ?>" value="<?= (int)$a['sortOrder'] ?>" min="0"></div>
  125. </td>
  126. <td>
  127. <div class="view"><?php if ($a['hidden']): ?><span class="badge badge-secret">Secret</span><?php endif; ?></div>
  128. <div class="edit"><input type="checkbox" name="hidden" value="1" form="edit-form-<?= $id ?>" <?= $a['hidden'] ? 'checked' : '' ?> aria-label="Hidden"></div>
  129. </td>
  130. <td>
  131. <div class="view actions-buttons">
  132. <button type="button" onclick="startEdit(<?= $id ?>)" class="btn btn-sm btn-teal">Edit</button>
  133. <form method="POST" onsubmit="return confirm('Delete this activity?')">
  134. <?= csrf_field() ?>
  135. <input type="hidden" name="action" value="delete">
  136. <input type="hidden" name="activityID" value="<?= $id ?>">
  137. <button class="btn btn-sm btn-danger">Delete</button>
  138. </form>
  139. </div>
  140. <div class="edit actions-buttons">
  141. <button type="submit" form="edit-form-<?= $id ?>" class="btn btn-sm btn-primary">💾 Save</button>
  142. <button type="button" onclick="cancelEdit(<?= $id ?>)" class="btn btn-sm btn-secondary">Cancel</button>
  143. </div>
  144. </td>
  145. </tr>
  146. <?php endforeach; ?>
  147. </tbody>
  148. </table>
  149. <script>
  150. function startEdit(id) {
  151. var row = document.getElementById('row-' + id);
  152. row.dataset.editing = 'true';
  153. var input = row.querySelector('.edit input[name="activityName"]');
  154. if (input) input.focus();
  155. }
  156. function cancelEdit(id) {
  157. document.getElementById('row-' + id).dataset.editing = 'false';
  158. }
  159. </script>
  160. <?php admin_foot(); ?>