diff --git a/assets/js/controllers/pagelist.js b/assets/js/controllers/pagelist.js
new file mode 100644
index 0000000..7da6872
--- /dev/null
+++ b/assets/js/controllers/pagelist.js
@@ -0,0 +1,63 @@
+import { Controller } from "@hotwired/stimulus"
+import { showToast } from "../services/toast";
+
+export default class PagelistController extends Controller {
+ static values = {
+ siteId: Number,
+ };
+
+ static targets = ["list"];
+
+ dragStart(ev) {
+ this.draggedRow = ev.currentTarget;
+ ev.currentTarget.classList.add("opacity-50");
+ ev.dataTransfer.effectAllowed = "move";
+ }
+
+ dragOver(ev) {
+ ev.preventDefault();
+ ev.dataTransfer.dropEffect = "move";
+ }
+
+ drop(ev) {
+ ev.preventDefault();
+ const targetRow = ev.currentTarget;
+ if (this.draggedRow && this.draggedRow !== targetRow) {
+ const rows = [...this.listTarget.children];
+ const draggedIdx = rows.indexOf(this.draggedRow);
+ const targetIdx = rows.indexOf(targetRow);
+ if (draggedIdx < targetIdx) {
+ targetRow.after(this.draggedRow);
+ } else {
+ targetRow.before(this.draggedRow);
+ }
+ this.saveOrder();
+ }
+ }
+
+ dragEnd(ev) {
+ ev.currentTarget.classList.remove("opacity-50");
+ this.draggedRow = null;
+ }
+
+ async saveOrder() {
+ const rows = [...this.listTarget.children];
+ const pageIds = rows.map(row => parseInt(row.dataset.pageId, 10));
+
+ try {
+ await fetch(`/sites/${this.siteIdValue}/pages/reorder`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "Accept": "application/json",
+ },
+ body: JSON.stringify({ page_ids: pageIds }),
+ });
+ } catch (error) {
+ showToast({
+ title: "Error",
+ body: "Failed to reorder pages.",
+ });
+ }
+ }
+}
diff --git a/assets/js/main.js b/assets/js/main.js
index d76c353..28451fb 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -7,6 +7,7 @@ import LogoutController from "./controllers/logout";
import FirstRunController from "./controllers/firstrun";
import UploadController from "./controllers/upload";
import ShowUploadController from "./controllers/show_upload";
+import PagelistController from "./controllers/pagelist";
window.Stimulus = Application.start()
Stimulus.register("toast", ToastController);
@@ -15,4 +16,5 @@ Stimulus.register("postedit", PosteditController);
Stimulus.register("logout", LogoutController);
Stimulus.register("first-run", FirstRunController);
Stimulus.register("upload", UploadController);
-Stimulus.register("show-upload", ShowUploadController);
\ No newline at end of file
+Stimulus.register("show-upload", ShowUploadController);
+Stimulus.register("pagelist", PagelistController);
\ No newline at end of file
diff --git a/views/_common/nav.html b/views/_common/nav.html
index e8bce30..ed7a1a9 100644
--- a/views/_common/nav.html
+++ b/views/_common/nav.html
@@ -13,6 +13,9 @@
Categories
+
+ Pages
+
Uploads
diff --git a/views/pages/index.html b/views/pages/index.html
new file mode 100644
index 0000000..3011c64
--- /dev/null
+++ b/views/pages/index.html
@@ -0,0 +1,35 @@
+
+
+
+ {{ if .pages }}
+
+
+
+ |
+ Title |
+ Slug |
+ Nav |
+
+
+
+ {{ range .pages }}
+
+ | ☰ |
+ {{ .Title }} |
+ {{ .Slug }} |
+ {{ if .ShowInNav }}Yes{{ end }} |
+
+ {{ end }}
+
+
+ {{ else }}
+
+ {{ end }}
+