import { ControlOutlined, FundProjectionScreenOutlined, MessageOutlined, QuestionCircleOutlined, SettingOutlined, SnippetsOutlined, TeamOutlined, WalletOutlined, } from "@ant-design/icons"; import { Divider, Flex, Form, Menu, Select, Typography } from "antd"; import { useEffect, useState } from "react"; import { useLocation, useNavigate, useParams } from "react-router-dom"; import { useDispatch, useSelector } from "react-redux"; import { setIsSideMenuCollapsed, setSideMenuComponentFirstRender, sideMenuComponentFirstRender, } from "./sideMenuSlice"; import { ItemType, MenuItemType } from "antd/es/menu/interface"; import { BreakpointLgWidth, BrowserTabSession, Constants, } from "core/utils/utils"; import Search from "antd/es/input/Search"; import { MyContainer } from "shared/components/MyContainer"; import { addLessonContent, currentLessonId, lessonState, } from "features/Lessons/LessonPageEditor/lessonPageEditorSlice"; import { Component, componentsGroups } from "features/Lessons/components"; import { darkMode, logoUrl } from "core/reducers/appSlice"; import { DndContext, DragOverlay } from "@dnd-kit/core"; import { createPortal } from "react-dom"; import { LessonState } from "core/types/lesson"; import { useForm } from "antd/es/form/Form"; import { useAddLessonContentMutation, useUpdateLessonStateMutation, } from "core/services/lessons"; import webSocketService, { addWebSocketReconnectListener, removeWebSocketReconnectListener, } from "core/services/websocketService"; import { WebSocketSendMessagesCmds } from "core/utils/webSocket"; export function SideMenuContent() { const location = useLocation(); const [selectedKeys, setSelectedKeys] = useState("/"); const [openKeys, setOpenKeys] = useState([""]); const dispatch = useDispatch(); const componentFirstRender = useSelector(sideMenuComponentFirstRender); const appLogoUrl = useSelector(logoUrl); const navigate = useNavigate(); const getFirstMenuItems = (): ItemType[] => { let items: ItemType[] = []; // overview let overviewGroup: ItemType = { key: "overviewGroup", label: "OVERVIEW", type: "group", children: [], }; if (overviewGroup.children) { overviewGroup.children.push({ key: Constants.ROUTE_PATHS.BOARD, label: "Board", icon: , }); overviewGroup.children.push({ key: Constants.ROUTE_PATHS.LESSIONS.ROOT, label: "Lessons", icon: , }); } items.push(overviewGroup); // organization let organizationGroup: ItemType = { key: "organizationGroup", label: "ORGANIZATION", type: "group", children: [], }; if (organizationGroup.children) { organizationGroup.children.push({ key: Constants.ROUTE_PATHS.ORGANIZATION_TEAM, label: "Team", icon: , }); organizationGroup.children.push({ key: Constants.ROUTE_PATHS.ORGANIZATION_ROLES, label: "Roles", icon: , }); organizationGroup.children.push({ key: Constants.ROUTE_PATHS.ORGANIZATION_SETTINGS, label: "Settings", icon: , }); } items.push(organizationGroup); return items; }; const getSecondMenuItems = (): ItemType[] => { let items: ItemType[] = []; // support items.push({ key: Constants.ROUTE_PATHS.WHATS_NEW, label: "What's New", icon: , }); // feedback items.push({ key: Constants.ROUTE_PATHS.SUGGEST_FEATURE, label: "Suggest a Feature", icon: , }); // payment plan items.push({ key: Constants.ROUTE_PATHS.CONTACT_SUPPORT, label: "Contact Support", icon: , }); return items; }; useEffect(() => { const pathname = location.pathname; setSelectedKeys(pathname); const subscribeTopicMessage = () => { webSocketService.send({ Cmd: WebSocketSendMessagesCmds.SubscribeToTopic, Body: { topic: pathname, browserTabSession: BrowserTabSession, }, }); }; subscribeTopicMessage(); addWebSocketReconnectListener(subscribeTopicMessage); let path = pathname.split("/"); if (path.length > 2) { // /store/:storeId/:subPage - open the store menu setOpenKeys([`/${path[1]}/${path[2]}`]); } // auto close sideMenu on mobile // this will prevent to auto close sideMenu on first render as the useEffects will be called after the first render if (componentFirstRender) { dispatch(setSideMenuComponentFirstRender(false)); } else if (document.body.clientWidth < BreakpointLgWidth) { dispatch(setIsSideMenuCollapsed(true)); } return () => removeWebSocketReconnectListener(subscribeTopicMessage); }, [location.pathname]); return (
{appLogoUrl !== null && ( logo )} navigate(item.key)} theme="light" selectedKeys={[selectedKeys]} items={getFirstMenuItems()} openKeys={openKeys} onOpenChange={(openKeys) => setOpenKeys( openKeys[openKeys.length - 1] ? [openKeys[openKeys.length - 1]] : [] ) } />
navigate(item.key)} items={getSecondMenuItems()} />
); } export function SideMenuEditorContent() { // create is dragging useState const [isDragging, setIsDragging] = useState(null); const { lessonId } = useParams(); const [form] = useForm(); const lnState = useSelector(lessonState); const currentLnId = useSelector(currentLessonId); const [updateLessonState] = useUpdateLessonStateMutation(); useEffect(() => { form.setFieldsValue({ state: lnState, }); }, [lnState]); return ( { console.log("drag start", event.active.id); setIsDragging(event.active.id.toString()); }} onDragEnd={(evnet) => { console.log("drag end", evnet.active.id); setIsDragging(null); }} > {componentsGroups.map((group, i) => (
{group.category} {group.components.map((component, i) => ( ))}
))} {createPortal( {isDragging ? (() => { const comp = componentsGroups .flatMap((group) => group.components) .find((comp) => "draggable_" + comp.name === isDragging); console.log("dragging", comp); if (!comp) { return null; } return (
); })() : null}
, document.body )}
); } export function DraggableCreateComponent({ component, }: { component: Component; }) { const dispatch = useDispatch(); /*const { attributes, listeners, setNodeRef, transform, isDragging, active } = useDraggable({ id: "draggable_" + component.name, });*/ return ( <>
); } function CreateComponent({ component }: { component: Component }) { const dispatch = useDispatch(); const isDarkMode = useSelector(darkMode); const currentLnId = useSelector(currentLessonId); const [reqAddLessonContent] = useAddLessonContentMutation(); return ( { console.log("insert component", component.type); try { const res = await reqAddLessonContent({ lessonId: currentLnId, type: component.type, data: component.defaultData || "", }).unwrap(); console.log("add content", component); dispatch( addLessonContent({ Id: res.Id, Type: component.type, Data: component.defaultData || "", Page: 1, Position: 1, }) ); } catch (err) { console.log("error", err); } }} > {component.thumbnail ? (
) : null} {component.name}
); } //console.log("insert component", component.type); //dispatch(addLessonContent(component.type));