list pages and dublicate + ....
This commit is contained in:
@@ -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]);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user