diff --git a/assets/pasted-20260319-061300-6728d60c.jpg b/assets/pasted-20260319-061300-6728d60c.jpg new file mode 100644 index 0000000..706c29c Binary files /dev/null and b/assets/pasted-20260319-061300-6728d60c.jpg differ diff --git a/assets/pasted-20260319-061442-0a583e0c.png b/assets/pasted-20260319-061442-0a583e0c.png new file mode 100644 index 0000000..b5d8e93 Binary files /dev/null and b/assets/pasted-20260319-061442-0a583e0c.png differ diff --git a/frontend/public/assets/vm-shot-2026-03-19T06-13-19-234Z.jpg b/frontend/public/assets/vm-shot-2026-03-19T06-13-19-234Z.jpg new file mode 100644 index 0000000..82c0ca1 Binary files /dev/null and b/frontend/public/assets/vm-shot-2026-03-19T06-13-19-234Z.jpg differ diff --git a/frontend/public/assets/vm-shot-2026-03-19T06-13-54-729Z.jpg b/frontend/public/assets/vm-shot-2026-03-19T06-13-54-729Z.jpg new file mode 100644 index 0000000..706c29c Binary files /dev/null and b/frontend/public/assets/vm-shot-2026-03-19T06-13-54-729Z.jpg differ diff --git a/frontend/src/pages/constructor.tsx b/frontend/src/pages/constructor.tsx index b24a498..acfe24f 100644 --- a/frontend/src/pages/constructor.tsx +++ b/frontend/src/pages/constructor.tsx @@ -146,6 +146,10 @@ type EditorMenuItem = | 'background_audio' | 'create_transition'; +type ConstructorPageProps = { + mode?: 'constructor' | 'element_edit'; +}; + const parseJsonObject = (value?: unknown, fallback?: T): T => { if (!value) return (fallback || ({} as T)) as T; @@ -524,17 +528,22 @@ const getElementButtonTitle = (element: CanvasElement) => { return element.label; }; -const ConstructorPage = () => { +const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => { const router = useRouter(); const canvasRef = useRef(null); const elementEditorRef = useRef(null); const [isAuthReady, setIsAuthReady] = useState(false); + const isElementEditMode = mode === 'element_edit'; const projectId = useMemo(() => { const value = router.query.projectId; if (Array.isArray(value)) return value[0] || ''; return String(value || ''); }, [router.query.projectId]); + const pageElementsListHref = useMemo(() => { + if (!projectId) return '/page_elements/page_elements-list'; + return `/page_elements/page_elements-list?projectId=${encodeURIComponent(projectId)}`; + }, [projectId]); const pageIdFromRoute = useMemo(() => { const value = router.query.pageId; @@ -925,8 +934,12 @@ const ConstructorPage = () => { useEffect(() => { if (!router.isReady) return; if (projectId) return; - router.replace('/projects/projects-list'); - }, [projectId, router]); + router.replace( + isElementEditMode + ? '/page_elements/page_elements-list' + : '/projects/projects-list', + ); + }, [isElementEditMode, projectId, router]); useEffect(() => { loadData(); @@ -1939,7 +1952,9 @@ const ConstructorPage = () => { return ( <> - {getPageTitle('Constructor')} + + {getPageTitle(isElementEditMode ? 'Edit Element' : 'Constructor')} +
@@ -1957,7 +1972,7 @@ const ConstructorPage = () => {

) : null} - {pages.length > 0 && ( + {pages.length > 0 && !isElementEditMode && (
setLabel(event.target.value)} + disabled={!hasUpdatePermission} + /> +
+
+ + +
+
+ + setXPercent(event.target.value)} + disabled={!hasUpdatePermission} + /> +
+
+ + setYPercent(event.target.value)} + disabled={!hasUpdatePermission} + /> +
+
+ + setAppearDelaySec(event.target.value)} + disabled={!hasUpdatePermission} + /> +
+
+ + setAppearDurationSec(event.target.value)} + placeholder='Leave empty for none' + disabled={!hasUpdatePermission} + /> +
+
+ + + +

Navigation / Text Settings

+
+
+ + setNavLabel(event.target.value)} + disabled={!hasUpdatePermission} + /> +
+
+ + setTooltipTitle(event.target.value)} + disabled={!hasUpdatePermission} + /> +
+
+ +