code refactor

This commit is contained in:
2025-09-29 14:51:00 +05:30
parent 2e3971102f
commit f847d058c2
5 changed files with 136 additions and 100 deletions

View File

@@ -99,7 +99,7 @@ const Outline: React.FC = () => {
</section> */} </section> */}
<section className="outline-section overflow"> <section className="outline-section overflow">
{/* <DropDownList value="Buildings" items={buildingsList} isOpen={isBuildingsOpen} onToggle={() => setIsBuildingsOpen((prev) => !prev)} showKebabMenu={false} showAddIcon={false} /> */} {/* <DropDownList value="Buildings" items={buildingsList} isOpen={isBuildingsOpen} onToggle={() => setIsBuildingsOpen((prev) => !prev)} showKebabMenu={false} showAddIcon={false} /> */}
<DropDownList header="Zones" type="Zones" items={sceneAssetsDataList} isDefaultOpen={true} showKebabMenu={false} showAddIcon={false} /> <DropDownList header="Zones" items={sceneAssetsDataList} isDefaultOpen={true} showKebabMenu={false} showAddIcon={false} />
</section> </section>
</div> </div>
)} )}

View File

@@ -5,7 +5,6 @@ import List from "./OutlineList/ListNew";
interface DropDownListProps { interface DropDownListProps {
header?: string; header?: string;
type?: "Zones" | "Assets";
items?: { id: string; name: string }[]; items?: { id: string; name: string }[];
showFocusIcon?: boolean; showFocusIcon?: boolean;
onFocusClick?: () => void; onFocusClick?: () => void;
@@ -21,7 +20,6 @@ interface DropDownListProps {
const DropDownList: React.FC<DropDownListProps> = ({ const DropDownList: React.FC<DropDownListProps> = ({
header = "Dropdown", header = "Dropdown",
items = [], items = [],
type = "Assets",
showFocusIcon = false, showFocusIcon = false,
onFocusClick, onFocusClick,
showAddIcon = true, showAddIcon = true,

View File

@@ -2,44 +2,40 @@ import React, { useState } from "react";
import { KebebIcon } from "../../icons/ExportCommonIcons"; import { KebebIcon } from "../../icons/ExportCommonIcons";
interface KebabMenuListProps { interface KebabMenuListProps {
items: string[]; // Array of menu items items: string[]; // Array of menu items
onSelect?: (item: string) => void; // Callback when a menu item is selected onSelect?: (item: string) => void; // Callback when a menu item is selected
} }
const KebabMenuList: React.FC<KebabMenuListProps> = ({ items, onSelect }) => { const KebabMenuList: React.FC<KebabMenuListProps> = ({ items, onSelect }) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const handleToggle = () => { const handleToggle = () => {
setIsOpen((prev) => !prev); setIsOpen((prev) => !prev);
}; };
const handleItemClick = (item: string) => { const handleItemClick = (item: string) => {
if (onSelect) { if (onSelect) {
onSelect(item); onSelect(item);
} }
setIsOpen(false); // Close menu after selection setIsOpen(false); // Close menu after selection
}; };
return ( return (
<div className="kebab-menu-container"> <div className="kebab-menu-container">
<div className="kebab-icon" onClick={handleToggle}> <div className="kebab-icon" onClick={handleToggle}>
<KebebIcon /> <KebebIcon />
</div>
{isOpen && (
<div className="menu-list">
{items.map((item, index) => (
<div
key={index}
className="menu-item"
onClick={() => handleItemClick(item)}
>
{item}
</div> </div>
))} {isOpen && (
<div className="menu-list">
{items.map((item, index) => (
<div key={index} className="menu-item" onClick={() => handleItemClick(item)}>
{item}
</div>
))}
</div>
)}
</div> </div>
)} );
</div>
);
}; };
export default KebabMenuList; export default KebabMenuList;

View File

@@ -2,81 +2,66 @@ import React, { useEffect, useRef, useState } from "react";
import { KebebIcon, TickIcon } from "../../icons/ExportCommonIcons"; import { KebebIcon, TickIcon } from "../../icons/ExportCommonIcons";
interface KebabMenuListMultiSelectProps { interface KebabMenuListMultiSelectProps {
items: { id: string; name: string }[]; // Array of menu items with id and name items: { id: string; name: string }[]; // Array of menu items with id and name
onSelectionChange?: (selectedItems: string[]) => void; // Callback for selected items onSelectionChange?: (selectedItems: string[]) => void; // Callback for selected items
} }
const KebabMenuListMultiSelect: React.FC<KebabMenuListMultiSelectProps> = ({ const KebabMenuListMultiSelect: React.FC<KebabMenuListMultiSelectProps> = ({ items, onSelectionChange }) => {
items, const [isOpen, setIsOpen] = useState(false);
onSelectionChange, const [selectedItems, setSelectedItems] = useState<string[]>([]);
}) => { const menuRef = useRef<HTMLDivElement>(null); // Ref to track the container
const [isOpen, setIsOpen] = useState(false);
const [selectedItems, setSelectedItems] = useState<string[]>([]);
const menuRef = useRef<HTMLDivElement>(null); // Ref to track the container
const handleToggle = () => { const handleToggle = () => {
setIsOpen((prev) => !prev); setIsOpen((prev) => !prev);
};
const handleItemToggle = (id: string) => {
setSelectedItems((prevSelected) => {
const isAlreadySelected = prevSelected.includes(id);
const updatedSelection = isAlreadySelected
? prevSelected.filter((item) => item !== id) // Deselect if already selected
: [...prevSelected, id]; // Add to selection if not selected
if (onSelectionChange) {
onSelectionChange(updatedSelection);
}
return updatedSelection;
});
};
// Close menu if clicked outside
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
}; };
document.addEventListener("mousedown", handleClickOutside); const handleItemToggle = (id: string) => {
return () => { setSelectedItems((prevSelected) => {
document.removeEventListener("mousedown", handleClickOutside); const isAlreadySelected = prevSelected.includes(id);
}; const updatedSelection = isAlreadySelected
}, []); ? prevSelected.filter((item) => item !== id) // Deselect if already selected
: [...prevSelected, id]; // Add to selection if not selected
return ( if (onSelectionChange) {
<div className="kebab-menu-container" ref={menuRef}> onSelectionChange(updatedSelection);
<div className="kebab-icon" onClick={handleToggle}> }
<KebebIcon />
</div> return updatedSelection;
{isOpen && ( });
<div className="menu-list"> };
{items.map((item) => (
<div // Close menu if clicked outside
key={item.id} useEffect(() => {
className={`menu-item ${ const handleClickOutside = (event: MouseEvent) => {
selectedItems.includes(item.id) ? "selected" : "" if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
}`} setIsOpen(false);
onClick={() => handleItemToggle(item.id)} }
> };
<input
type="checkbox" document.addEventListener("mousedown", handleClickOutside);
checked={selectedItems.includes(item.id)} return () => {
onChange={() => handleItemToggle(item.id)} document.removeEventListener("mousedown", handleClickOutside);
/> };
<div className="icon-container"> }, []);
{selectedItems.includes(item.id) && <TickIcon />}
</div> return (
{item.name} <div className="kebab-menu-container" ref={menuRef}>
<div className="kebab-icon" onClick={handleToggle}>
<KebebIcon />
</div> </div>
))} {isOpen && (
<div className="menu-list">
{items.map((item) => (
<div key={item.id} className={`menu-item ${selectedItems.includes(item.id) ? "selected" : ""}`} onClick={() => handleItemToggle(item.id)}>
<input type="checkbox" checked={selectedItems.includes(item.id)} onChange={() => handleItemToggle(item.id)} />
<div className="icon-container">{selectedItems.includes(item.id) && <TickIcon />}</div>
{item.name}
</div>
))}
</div>
)}
</div> </div>
)} );
</div>
);
}; };
export default KebabMenuListMultiSelect; export default KebabMenuListMultiSelect;

View File

@@ -78,3 +78,60 @@ interface Tutorial {
thumbnail?: string; thumbnail?: string;
createdAt: string; createdAt: string;
} }
// Base interface for all list items
interface BaseListItem {
id: string;
name: string;
type: "zone" | "asset" | "wall" | "floor" | "point" | "decal";
isLocked?: boolean;
isVisible?: boolean;
isActive?: boolean;
canEdit?: boolean;
children?: ListItem[]; // For nested relationships
metadata?: {
position?: [number, number, number];
rotation?: [number, number, number];
scale?: [number, number, number];
color?: string;
height?: number;
thickness?: number;
// ... other type-specific properties
};
}
// Extended interfaces for specific types
interface ZoneListItem extends BaseListItem {
type: "zone";
metadata: {
zoneHeight: number;
zoneColor: string;
viewPortPosition: [number, number, number];
viewPortTarget: [number, number, number];
};
}
interface AssetListItem extends BaseListItem {
type: "asset";
metadata: {
modelUuid: string;
position: [number, number, number];
rotation: [number, number, number];
scale: [number, number, number];
isCollidable: boolean;
opacity: number;
animations?: string[];
};
}
interface WallListItem extends BaseListItem {
type: "wall";
metadata: {
wallThickness: number;
wallHeight: number;
outsideMaterial: string;
insideMaterial: string;
};
}
type ListItem = ZoneListItem | AssetListItem | WallListItem | BaseListItem;