diff --git a/src/pages/editor/components/PagesPanel.tsx b/src/pages/editor/components/PagesPanel.tsx index 4662565..8214666 100644 --- a/src/pages/editor/components/PagesPanel.tsx +++ b/src/pages/editor/components/PagesPanel.tsx @@ -1,4 +1,5 @@ import { Copy, Trash, AddSquare, DocumentText } from 'iconsax-react' +import { useState } from 'react' import { useEditorStore } from '../store/editorStore' import type { Page } from '../store/editorStore.types' import { clx } from '@/helpers/utils' @@ -25,7 +26,10 @@ const PagesPanel = ({ catalogSize }: PagesPanelProps) => { addPage, duplicatePage, deletePage, + reorderPages, } = useEditorStore() + const [draggedPageId, setDraggedPageId] = useState(null) + const [dragOverPageId, setDragOverPageId] = useState(null) const handleAddPage = () => { addPage() @@ -57,8 +61,33 @@ const PagesPanel = ({ catalogSize }: PagesPanelProps) => {
setCurrentPage(page.id)} + draggable + onDragStart={() => { + setDraggedPageId(page.id) + }} + onDragOver={(e) => { + e.preventDefault() + if (dragOverPageId !== page.id) { + setDragOverPageId(page.id) + } + }} + onDrop={(e) => { + e.preventDefault() + if (draggedPageId && draggedPageId !== page.id) { + reorderPages(draggedPageId, page.id) + } + setDraggedPageId(null) + setDragOverPageId(null) + }} + onDragEnd={() => { + setDraggedPageId(null) + setDragOverPageId(null) + }} className={clx( 'flex flex-col gap-2 cursor-pointer transition-colors', + dragOverPageId === page.id && + draggedPageId !== page.id && + 'ring-2 ring-blue-300 rounded-lg', isSelected && ' rounded-lg p-0.5' )} > diff --git a/src/pages/editor/store/editorStore.helpers.ts b/src/pages/editor/store/editorStore.helpers.ts index 27b7ae7..3416214 100644 --- a/src/pages/editor/store/editorStore.helpers.ts +++ b/src/pages/editor/store/editorStore.helpers.ts @@ -67,11 +67,20 @@ export const createInitialPage = (name: string): Page => ({ backgroundImageUrl: "", }); -export const reorderByIds = ( - items: EditorObject[], +export const getDefaultPageName = (index: number): string => + index === 0 ? "جلد" : String(index + 1); + +export const applyDefaultPageNames = (pages: Page[]): Page[] => + pages.map((page, index) => ({ + ...page, + name: getDefaultPageName(index), + })); + +export const reorderByIds = ( + items: T[], draggedId: string, targetId: string, -) => { +): T[] => { const fromIndex = items.findIndex((item) => item.id === draggedId); const toIndex = items.findIndex((item) => item.id === targetId); diff --git a/src/pages/editor/store/editorStore.ts b/src/pages/editor/store/editorStore.ts index a39269f..4b38aab 100644 --- a/src/pages/editor/store/editorStore.ts +++ b/src/pages/editor/store/editorStore.ts @@ -8,6 +8,7 @@ import { createTableCellId, isInvalidPageId, reorderByIds, + applyDefaultPageNames, ungroupById, normalizePageObjects, } from "./editorStore.helpers"; @@ -143,6 +144,7 @@ type EditorStoreType = { addPage: (name?: string) => void; duplicatePage: (pageId: string) => void; deletePage: (pageId: string) => void; + reorderPages: (draggedId: string, targetId: string) => void; setCurrentPage: (pageId: string) => void; updatePageName: (pageId: string, name: string) => void; toggleObjectVisibility: (id: string) => void; @@ -875,7 +877,7 @@ export const useEditorStore = create((set, get) => { const newCurrentPage = newPages.find((p) => p.id === newCurrentPageId); set({ - pages: newPages, + pages: applyDefaultPageNames(newPages), currentPageId: newCurrentPageId, objects: newCurrentPage?.objects || [], guides: newCurrentPage?.guides || [], @@ -884,6 +886,25 @@ export const useEditorStore = create((set, get) => { objectHistoryFuture: [], }); }, + reorderPages: (draggedId, targetId) => { + if (draggedId === targetId) return; + + set((state) => { + const pagesWithCurrentObjects = state.currentPageId + ? state.pages.map((p) => + p.id === state.currentPageId + ? { ...p, objects: state.objects, guides: state.guides } + : p, + ) + : state.pages; + + return { + pages: applyDefaultPageNames( + reorderByIds(pagesWithCurrentObjects, draggedId, targetId), + ), + }; + }); + }, setCurrentPage: (pageId) => { const state = get(); const targetPage = state.pages.find((p) => p.id === pageId);