diff --git a/frontend/index.html b/frontend/index.html
index b73f59a..c54a1f2 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -190,6 +190,14 @@
color: #fff;
}
+ .sub-nav-item.view-dragging {
+ opacity: 0.55;
+ }
+
+ .sub-nav-item.view-drag-over {
+ box-shadow: inset 0 2px 0 #4a9adf;
+ }
+
.column-header-inner {
position: relative;
display: flex;
@@ -11172,6 +11180,25 @@
const [activeGridView, setActiveGridView] = useState('view-main');
const [gridUiAction, setGridUiAction] = useState(null);
const [sidebarContextMenu, setSidebarContextMenu] = useState(null);
+ const [draggingViewId, setDraggingViewId] = useState(null);
+ const [dragOverViewId, setDragOverViewId] = useState(null);
+
+ // Drag-reorder the saved grid views in the sidebar. Mirrors moveColumnBefore:
+ // mutate gridViews only — the grid page's autosave (which has `views` in its
+ // snapshot + deps) persists the new order to /api/fundraising/state, same path
+ // rename/delete already use.
+ const moveViewBefore = (fromId, targetId) => {
+ if (!fromId || !targetId || fromId === targetId) return;
+ setGridViews((prev) => {
+ const fromIndex = prev.findIndex((v) => v.id === fromId);
+ const targetIndex = prev.findIndex((v) => v.id === targetId);
+ if (fromIndex < 0 || targetIndex < 0 || fromIndex === targetIndex) return prev;
+ const next = [...prev];
+ const [moved] = next.splice(fromIndex, 1);
+ next.splice(targetIndex, 0, moved);
+ return next;
+ });
+ };
useEffect(() => {
localStorage.setItem(GRID_VIEW_STORAGE_KEY, JSON.stringify(gridViews));
@@ -11308,12 +11335,38 @@
{gridViews.map((v) => (