- Removed CalculateAreaGroup and computeArea function as they were no longer needed. - Updated Floor2DInstance and Zone2DInstance to calculate area and centroid using new utility functions. - Refactored WallInstances to include Floor2D rendering and improved area display. - Cleaned up imports and ensured consistent formatting across files. - Enhanced performance by memoizing calculations for area and centroid. - Removed deprecated state management for rooms and version history visibility.
253 lines
9.0 KiB
TypeScript
253 lines
9.0 KiB
TypeScript
import React, { useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { ArrowIcon } from "../../icons/ExportCommonIcons";
|
|
import { toggleTheme } from "../../../utils/theme";
|
|
import { useShortcutStore } from "../../../store/builder/store";
|
|
import useModuleStore, { useSubModuleStore } from "../../../store/ui/useModuleStore";
|
|
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
|
|
|
interface MenuBarProps {
|
|
setOpenMenu: (isOpen: boolean) => void;
|
|
}
|
|
|
|
interface MenuItem {
|
|
label: string;
|
|
onClick?: string;
|
|
shortcut?: string;
|
|
submenu?: MenuItem[];
|
|
action?: () => void;
|
|
}
|
|
|
|
const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
|
|
const navigate = useNavigate();
|
|
const [activeMenu, setActiveMenu] = useState<string | null>(null);
|
|
const [activeSubMenu, setActiveSubMenu] = useState<string | null>(null);
|
|
const [selectedItems, setSelectedItems] = useState<Record<string, boolean>>({});
|
|
|
|
const { versionStore } = useSceneContext();
|
|
const { setCreateNewVersion, setVersionHistoryVisible } = versionStore();
|
|
const { setActiveModule } = useModuleStore();
|
|
const { setSubModule } = useSubModuleStore();
|
|
const { showShortcuts, setShowShortcuts } = useShortcutStore();
|
|
|
|
const savedTheme = localStorage.getItem("theme") ?? "light";
|
|
|
|
const toggleSelection = (itemName: string) => {
|
|
setSelectedItems((prev) => ({
|
|
...prev,
|
|
[itemName]: !prev[itemName],
|
|
}));
|
|
};
|
|
|
|
// functions
|
|
const handleThemeChange = () => {
|
|
toggleTheme();
|
|
window.location.reload();
|
|
};
|
|
|
|
const handleLogout = () => {
|
|
const theme = localStorage.getItem("theme") ?? "light";
|
|
localStorage.clear();
|
|
localStorage.setItem("theme", theme);
|
|
navigate("/");
|
|
};
|
|
|
|
function handleShotcutsHelper() {
|
|
setShowShortcuts(!showShortcuts);
|
|
}
|
|
|
|
function handleVersionCreation() {
|
|
setCreateNewVersion(true);
|
|
setVersionHistoryVisible(true);
|
|
setSubModule("properties");
|
|
setActiveModule("builder");
|
|
}
|
|
|
|
const menus: Record<string, MenuItem[]> = {
|
|
File: [
|
|
{ label: "New File", shortcut: "Ctrl + N" },
|
|
{ label: "Open Local File", shortcut: "Ctrl + O" },
|
|
{
|
|
label: "Save Version",
|
|
shortcut: "Ctrl + Alt + S",
|
|
action: handleVersionCreation,
|
|
},
|
|
{ label: "Make a Copy" },
|
|
{ label: "Share" },
|
|
{ label: "Rename" },
|
|
{ label: "Import" },
|
|
{ label: "Close File" },
|
|
],
|
|
Edit: [
|
|
{ label: "Undo", shortcut: "Ctrl + Z" },
|
|
{ label: "Redo", shortcut: "Ctrl + Shift + Z" },
|
|
{ label: "Undo History" },
|
|
{ label: "Redo History" },
|
|
{ label: "Find", shortcut: "Ctrl + F" },
|
|
{ label: "Delete" },
|
|
{ label: "Select by..." },
|
|
{ label: "Keymap" },
|
|
],
|
|
View: [
|
|
{ label: "Grid" },
|
|
{
|
|
label: "Gizmo",
|
|
submenu: [{ label: "Visibility" }, { label: "Cube view" }, { label: "Sphere view" }],
|
|
},
|
|
{ label: "Zoom" },
|
|
{ label: "Full Screen", shortcut: "F11" },
|
|
],
|
|
Help: [
|
|
{
|
|
label: "Shortcuts",
|
|
shortcut: "Ctrl + Shift + ?",
|
|
action: handleShotcutsHelper,
|
|
},
|
|
{ label: "Manual" },
|
|
{ label: "Video Tutorials" },
|
|
{ label: "Report a bug" },
|
|
],
|
|
};
|
|
|
|
// render menu item and sub menu item component
|
|
const renderMenuItem = ({ label, shortcut, action }: MenuItem) => (
|
|
<button
|
|
id={label}
|
|
className="menu-item-container"
|
|
key={label}
|
|
onClick={() => {
|
|
toggleSelection(label);
|
|
if (action) action();
|
|
}}
|
|
>
|
|
<div className="menu-item">
|
|
<span>
|
|
{selectedItems[label] ? "✓ " : ""}
|
|
{label}
|
|
</span>
|
|
{shortcut && (
|
|
<div className="menu-item-right">
|
|
<span className="shortcut">{shortcut}</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</button>
|
|
);
|
|
|
|
const renderSubMenu = (submenu: MenuItem[], parentLabel: string) => (
|
|
<div className="submenu">
|
|
{submenu.map((item) => (
|
|
<button
|
|
id={item.label}
|
|
key={item.label}
|
|
className="submenu-item"
|
|
onClick={() => {
|
|
console.log("hi", item.onClick);
|
|
toggleSelection(item.label);
|
|
}}
|
|
>
|
|
<span>
|
|
{selectedItems[item.label] ? "✓ " : ""}
|
|
{item.label}
|
|
</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<div className="menu-bar" onPointerLeave={() => setOpenMenu(false)}>
|
|
<div className="menu-buttons">
|
|
{Object.entries(menus).map(([menu, items]) => (
|
|
<button
|
|
id={menu}
|
|
key={menu}
|
|
className="menu-button-container"
|
|
onMouseEnter={() => setActiveMenu(menu)}
|
|
onMouseLeave={() => {
|
|
setActiveMenu(null);
|
|
setActiveSubMenu(null);
|
|
}}
|
|
>
|
|
<div className="menu-button">
|
|
{menu}
|
|
<span className="dropdown-icon">
|
|
<ArrowIcon />
|
|
</span>
|
|
</div>
|
|
|
|
{activeMenu === menu && (
|
|
<div className="dropdown-menu">
|
|
{items.map((item) =>
|
|
item.submenu ? (
|
|
<button
|
|
id={item.label}
|
|
key={item.label}
|
|
className="menu-item-container"
|
|
onMouseEnter={() => setActiveSubMenu(item.label)}
|
|
onMouseLeave={() => setActiveSubMenu(null)}
|
|
>
|
|
<div className="menu-item">
|
|
<span>{item.label}</span>
|
|
<span className="dropdown-icon">
|
|
<ArrowIcon />
|
|
</span>
|
|
</div>
|
|
{activeSubMenu === item.label && renderSubMenu(item.submenu, item.label)}
|
|
</button>
|
|
) : (
|
|
renderMenuItem(item)
|
|
)
|
|
)}
|
|
</div>
|
|
)}
|
|
</button>
|
|
))}
|
|
|
|
{/* Version History */}
|
|
<button
|
|
id="version-history"
|
|
className="menu-button-container"
|
|
onMouseEnter={() => setActiveMenu("Version history")}
|
|
onMouseLeave={() => {
|
|
setActiveMenu(null);
|
|
setActiveSubMenu(null);
|
|
}}
|
|
onClick={() => {
|
|
setVersionHistoryVisible(true);
|
|
setSubModule("properties");
|
|
setActiveModule("builder");
|
|
}}
|
|
>
|
|
<div className="menu-button">
|
|
Version history <div className="value">Ctrl + H</div>
|
|
</div>
|
|
</button>
|
|
|
|
{/* Theme */}
|
|
<button
|
|
id="theme-btn"
|
|
className="menu-button-container"
|
|
onMouseEnter={() => setActiveMenu("Theme")}
|
|
onMouseLeave={() => {
|
|
setActiveMenu(null);
|
|
setActiveSubMenu(null);
|
|
}}
|
|
onClick={handleThemeChange}
|
|
>
|
|
<div className="menu-button">
|
|
Theme <div className="value">{savedTheme}</div>
|
|
</div>
|
|
</button>
|
|
|
|
{/* Log out */}
|
|
<button id="logout" className="menu-button-container" onClick={handleLogout}>
|
|
<div className="menu-button">Log out</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MenuBar;
|