list pages and dublicate + ....

This commit is contained in:
hamid zarghami
2025-12-31 12:29:57 +03:30
parent bcb66039d2
commit 26d0f5eb53
3 changed files with 53 additions and 5 deletions
+5 -5
View File
@@ -1,4 +1,4 @@
import { DocumentText, Layer, Eye, Lock, Trash, ArrowRight2, Text, Shapes, Add, Copy } from 'iconsax-react' import { DocumentText, Layer, Eye, Trash, ArrowRight2, Text, Shapes, Add, Copy } from 'iconsax-react'
import { useEditorStore } from '../store/editorStore' import { useEditorStore } from '../store/editorStore'
import { clx } from '@/helpers/utils' import { clx } from '@/helpers/utils'
import { useState } from 'react' import { useState } from 'react'
@@ -12,7 +12,7 @@ type LayersPanelProps = {
const LayersPanel = ({ isOpen, setIsOpen }: LayersPanelProps) => { const LayersPanel = ({ isOpen, setIsOpen }: LayersPanelProps) => {
const [activeTab, setActiveTab] = useState<TabType>('pages') const [activeTab, setActiveTab] = useState<TabType>('pages')
const { objects, selectedObjectId, setSelectedObjectId, deleteObject } = useEditorStore() const { objects, selectedObjectId, setSelectedObjectId, deleteObject, duplicateObject } = useEditorStore()
const { const {
pages, pages,
currentPageId, currentPageId,
@@ -116,7 +116,7 @@ const LayersPanel = ({ isOpen, setIsOpen }: LayersPanelProps) => {
</button> </button>
</div> </div>
<div className="fixed border-l border-border left-20 top-[100px] bottom-4 z-30 flex flex-col w-[280px]"> <div className="fixed border-l border-border left-20 top-[100px] bottom-4 z-30 flex flex-col w-[232px]">
<div className="bg-white rounded-r-4xl flex flex-col h-full"> <div className="bg-white rounded-r-4xl flex flex-col h-full">
<div className="flex items-center justify-between p-4 border-b border-border"> <div className="flex items-center justify-between p-4 border-b border-border">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
@@ -234,11 +234,11 @@ const LayersPanel = ({ isOpen, setIsOpen }: LayersPanelProps) => {
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation() e.stopPropagation()
// TODO: Toggle lock duplicateObject(obj.id)
}} }}
className="w-6 h-6 flex items-center justify-center rounded-full hover:bg-gray-200 transition-colors" className="w-6 h-6 flex items-center justify-center rounded-full hover:bg-gray-200 transition-colors"
> >
<Lock size={16} color="black" /> <Copy size={16} color="black" />
</button> </button>
<button <button
onClick={(e) => { onClick={(e) => {
@@ -22,6 +22,7 @@ const ZoomControls = () => {
const rect = trackElement.getBoundingClientRect(); const rect = trackElement.getBoundingClientRect();
const x = clientX - rect.left; const x = clientX - rect.left;
const clampedX = Math.max(0, Math.min(SLIDER_WIDTH, x)); const clampedX = Math.max(0, Math.min(SLIDER_WIDTH, x));
// وقتی به راست می‌کشیم (clampedX بیشتر)، zoom باید بیشتر شود
const newZoom = MIN_ZOOM + (clampedX / SLIDER_WIDTH) * (MAX_ZOOM - MIN_ZOOM); const newZoom = MIN_ZOOM + (clampedX / SLIDER_WIDTH) * (MAX_ZOOM - MIN_ZOOM);
setZoom(newZoom); setZoom(newZoom);
}, [setZoom]); }, [setZoom]);
+47
View File
@@ -74,6 +74,7 @@ type EditorStoreType = {
addObject: (object: EditorObject) => void; addObject: (object: EditorObject) => void;
updateObject: (id: string, updates: Partial<EditorObject>) => void; updateObject: (id: string, updates: Partial<EditorObject>) => void;
deleteObject: (id: string) => void; deleteObject: (id: string) => void;
duplicateObject: (id: string) => void;
selectedObjectId: string | null; selectedObjectId: string | null;
setSelectedObjectId: (id: string | null) => void; setSelectedObjectId: (id: string | null) => void;
selectedTableId: string | null; selectedTableId: string | null;
@@ -240,6 +241,52 @@ export const useEditorStore = create<EditorStoreType>((set, get) => {
state.selectedTableId === id ? null : state.selectedTableId, state.selectedTableId === id ? null : state.selectedTableId,
})); }));
}, },
duplicateObject: (id) => {
const state = get();
const objectToDuplicate = state.objects.find((obj) => obj.id === id);
if (!objectToDuplicate) return;
const duplicatedObject: EditorObject = {
...objectToDuplicate,
id: `${objectToDuplicate.id}-${crypto.randomUUID()}`,
x: (objectToDuplicate.x || 0) + 20,
y: (objectToDuplicate.y || 0) + 20,
...(objectToDuplicate.tableData && {
tableData: {
...objectToDuplicate.tableData,
id: `table-${crypto.randomUUID()}`,
cells: Object.fromEntries(
Object.entries(objectToDuplicate.tableData.cells).map(
([key, cell]) => [
key,
{
...cell,
id: `cell-${crypto.randomUUID()}`,
},
]
)
),
},
}),
};
if (state.currentPageId) {
set((state) => ({
objects: [...state.objects, duplicatedObject],
pages: state.pages.map((p) =>
p.id === state.currentPageId
? { ...p, objects: [...p.objects, duplicatedObject] }
: p
),
selectedObjectId: duplicatedObject.id,
}));
return;
}
set((state) => ({
objects: [...state.objects, duplicatedObject],
selectedObjectId: duplicatedObject.id,
}));
},
selectedObjectId: null, selectedObjectId: null,
setSelectedObjectId: (id) => set({ selectedObjectId: id }), setSelectedObjectId: (id) => set({ selectedObjectId: id }),
selectedTableId: null, selectedTableId: null,