From 4152e611a9f0081c8edaf3f5b1ff503190e96796 Mon Sep 17 00:00:00 2001 From: Vishnu Date: Wed, 30 Apr 2025 10:10:39 +0530 Subject: [PATCH] refactor: Update dropdown items to include active state, enhance List and DropDownList components, and improve sidebar styles for better layout and accessibility --- .../components/layout/sidebarLeft/Outline.tsx | 2 +- app/src/components/ui/list/DropDownList.tsx | 63 ++++---- app/src/components/ui/list/List.tsx | 74 ++++----- app/src/styles/abstracts/variables.scss | 6 +- app/src/styles/components/lists.scss | 26 ++-- app/src/styles/layout/sidebar.scss | 140 ++++++------------ 6 files changed, 139 insertions(+), 172 deletions(-) diff --git a/app/src/components/layout/sidebarLeft/Outline.tsx b/app/src/components/layout/sidebarLeft/Outline.tsx index 417f069..152c357 100644 --- a/app/src/components/layout/sidebarLeft/Outline.tsx +++ b/app/src/components/layout/sidebarLeft/Outline.tsx @@ -11,7 +11,7 @@ const Outline: React.FC = () => { }; const dropdownItems = [ - { id: "1", name: "Ground Floor" }, + { id: "1", name: "Ground Floor", active: true }, // { id: "2", name: "Floor 1" }, ]; // Example dropdown items diff --git a/app/src/components/ui/list/DropDownList.tsx b/app/src/components/ui/list/DropDownList.tsx index 0416a9e..20c6951 100644 --- a/app/src/components/ui/list/DropDownList.tsx +++ b/app/src/components/ui/list/DropDownList.tsx @@ -3,7 +3,6 @@ import List from "./List"; import { AddIcon, ArrowIcon, FocusIcon } from "../../icons/ExportCommonIcons"; import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect"; import { useFloorItems, useZones } from "../../../store/store"; -import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore"; interface DropDownListProps { value?: string; // Value to display in the DropDownList @@ -17,6 +16,17 @@ interface DropDownListProps { remove?: boolean; } +interface Zone { + zoneId: string; + zoneName: string; + points: [number, number, number][]; // polygon vertices +} +interface ZoneData { + id: string; + name: string; + assets: { id: string; name: string; position?: []; rotation?: {} }[]; +} + const DropDownList: React.FC = ({ value = "Dropdown", items = [], @@ -33,38 +43,30 @@ const DropDownList: React.FC = ({ remove, }) => { const [isOpen, setIsOpen] = useState(defaultOpen); - const { zones, setZones } = useZones(); + const { zones } = useZones(); const handleToggle = () => { setIsOpen((prev) => !prev); // Toggle the state }; - interface Asset { - id: string; - name: string; - position: [number, number, number]; // x, y, z - } - interface Zone { - zoneId: string; - zoneName: string; - points: [number, number, number][]; // polygon vertices - } - interface ZoneData { - id: string; - name: string; - assets: { id: string; name: string; position?: []; rotation?: {} }[]; - } const [zoneDataList, setZoneDataList] = useState([]); const { floorItems } = useFloorItems(); - const isPointInsidePolygon = (point: [number, number], polygon: [number, number][]) => { + const isPointInsidePolygon = ( + point: [number, number], + polygon: [number, number][] + ) => { let inside = false; for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { - const xi = polygon[i][0], zi = polygon[i][1]; - const xj = polygon[j][0], zj = polygon[j][1]; + const xi = polygon[i][0], + zi = polygon[i][1]; + const xj = polygon[j][0], + zj = polygon[j][1]; - const intersect = ((zi > point[1]) !== (zj > point[1])) && - (point[0] < (xj - xi) * (point[1] - zi) / (zj - zi + 0.000001) + xi); + const intersect = + // eslint-disable-next-line no-mixed-operators + zi > point[1] !== zj > point[1] && + point[0] < ((xj - xi) * (point[1] - zi)) / (zj - zi + 0.000001) + xi; if (intersect) inside = !inside; } @@ -73,18 +75,21 @@ const DropDownList: React.FC = ({ useEffect(() => { const updatedZoneList: ZoneData[] = zones?.map((zone: Zone) => { - const polygon2D = zone.points.map((p: [number, number, number]) => [p[0], p[2]]) as [number, number][]; + const polygon2D = zone.points.map((p: [number, number, number]) => [ + p[0], + p[2], + ]); const assetsInZone = floorItems .filter((item: any) => { const [x, , z] = item.position; - return isPointInsidePolygon([x, z], polygon2D); + return isPointInsidePolygon([x, z], polygon2D as [number, number][]); }) .map((item: any) => ({ id: item.modeluuid, name: item.modelname, position: item.position, - rotation: item.rotation + rotation: item.rotation, })); return { @@ -99,9 +104,9 @@ const DropDownList: React.FC = ({ return (
-
+
+
{showFocusIcon && (
@@ -118,13 +123,13 @@ const DropDownList: React.FC = ({
)} -
-
+
{isOpen && ( diff --git a/app/src/components/ui/list/List.tsx b/app/src/components/ui/list/List.tsx index 06419af..bd8725b 100644 --- a/app/src/components/ui/list/List.tsx +++ b/app/src/components/ui/list/List.tsx @@ -12,7 +12,6 @@ import { LockIcon, RemoveIcon, } from "../../icons/ExportCommonIcons"; -import { useThree } from "@react-three/fiber"; import { useFloorItems, useZoneAssetId, useZones } from "../../../store/store"; import { zoneCameraUpdate } from "../../../services/visulization/zone/zoneCameraUpdation"; import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; @@ -32,20 +31,19 @@ interface ZoneItem { interface ListProps { items?: ZoneItem[]; - placeholder?: string; remove?: boolean; } const List: React.FC = ({ items = [], remove }) => { - const { activeModule, setActiveModule } = useModuleStore(); + const { activeModule } = useModuleStore(); const { selectedZone, setSelectedZone } = useSelectedZoneStore(); const { zoneAssetId, setZoneAssetId } = useZoneAssetId(); - const { zones, setZones } = useZones(); + const { zones } = useZones(); const { setSubModule } = useSubModuleStore(); const [expandedZones, setExpandedZones] = useState>( {} ); - const { floorItems, setFloorItems } = useFloorItems(); + const { setFloorItems } = useFloorItems(); useEffect(() => { useSelectedZoneStore.getState().setSelectedZone({ @@ -70,39 +68,36 @@ const List: React.FC = ({ items = [], remove }) => { async function handleSelectZone(id: string) { try { if (selectedZone?.zoneId === id) { - return; } setSubModule("zoneProperties"); const email = localStorage.getItem("email"); - const organization = email?.split("@")[1]?.split(".")[0] || ""; + const organization = email?.split("@")[1]?.split(".")[0] ?? ""; let response = await getZoneData(id, organization); setSelectedZone({ zoneName: response?.zoneName, - activeSides: response?.activeSides || [], - panelOrder: response?.panelOrder || [], - lockedPanels: response?.lockedPanels || [], - widgets: response?.widgets || [], + activeSides: response?.activeSides ?? [], + panelOrder: response?.panelOrder ?? [], + lockedPanels: response?.lockedPanels ?? [], + widgets: response?.widgets ?? [], zoneId: response?.zoneId, - zoneViewPortTarget: response?.viewPortCenter || [], - zoneViewPortPosition: response?.viewPortposition || [], + zoneViewPortTarget: response?.viewPortCenter ?? [], + zoneViewPortPosition: response?.viewPortposition ?? [], }); - - } catch (error) { - + console.log(error); } } function handleAssetClick(asset: Asset) { - setZoneAssetId(asset) + setZoneAssetId(asset); } async function handleZoneNameChange(newName: string) { - const email = localStorage.getItem("email") || ""; + const email = localStorage.getItem("email") ?? ""; const organization = email?.split("@")[1]?.split(".")[0]; const isDuplicate = zones.some( @@ -128,12 +123,16 @@ const List: React.FC = ({ items = [], remove }) => { } async function handleZoneAssetName(newName: string) { - const email = localStorage.getItem("email") || ""; + const email = localStorage.getItem("email") ?? ""; const organization = email?.split("@")[1]?.split(".")[0]; if (zoneAssetId?.id) { - let response = await setFloorItemApi(organization, zoneAssetId.id, newName) - console.log('response: ', response); + let response = await setFloorItemApi( + organization, + zoneAssetId.id, + newName + ); + console.log("response: ", response); setFloorItems((prevFloorItems: any[]) => prevFloorItems.map((floorItems) => floorItems.modeluuid === zoneAssetId.id @@ -160,7 +159,7 @@ const List: React.FC = ({ items = [], remove }) => {
  • -
    handleSelectZone(item.id)} > @@ -169,8 +168,7 @@ const List: React.FC = ({ items = [], remove }) => { onRename={handleZoneNameChange} checkDuplicate={checkZoneNameDuplicate} /> - -
    +
    @@ -185,12 +183,12 @@ const List: React.FC = ({ items = [], remove }) => {
    )} {item.assets && item.assets.length > 0 && ( -
    toggleZoneExpansion(item.id)} > -
    + )}
    @@ -206,20 +204,26 @@ const List: React.FC = ({ items = [], remove }) => { className="list-container asset-item" >
    -
    handleAssetClick(asset)} > - -
    +
    -
    +
    -
    + +
    + {remove && ( -
    +
    + )}
    diff --git a/app/src/styles/abstracts/variables.scss b/app/src/styles/abstracts/variables.scss index 2913425..37d9971 100644 --- a/app/src/styles/abstracts/variables.scss +++ b/app/src/styles/abstracts/variables.scss @@ -16,7 +16,7 @@ $text-button-color: #f3f3fd; $text-color-dark: #f3f3fd; $text-disabled-dark: #6f6f7a; $input-text-color-dark: #b5b5c8; -$highlight-text-color-dark: #b392f0; +$highlight-text-color-dark: #d2baff; $text-button-color-dark: #f3f3fd; // background colors @@ -105,8 +105,8 @@ $color5: #c7a8ff; // old variables $accent-color: #6f42c1; $accent-color-dark: #c4abf1; -$highlight-accent-color: #e0dfff; -$highlight-accent-color-dark: #403e6a; +// $highlight-accent-color: #e0dfff; +// $highlight-accent-color-dark: #403e6a; // $background-color: #fcfdfd; // $background-color-dark: #19191d; diff --git a/app/src/styles/components/lists.scss b/app/src/styles/components/lists.scss index 3b52e69..894eac1 100644 --- a/app/src/styles/components/lists.scss +++ b/app/src/styles/components/lists.scss @@ -34,9 +34,8 @@ padding: 12px; } - .list-container { + li.list-container { padding: 2px; - // margin-left: 10px; overflow: hidden; .list-item { @@ -45,11 +44,13 @@ text-align: center; padding: 4px 8px; border-radius: #{$border-radius-large}; - - .value { - width: 100%; - text-align: start; - max-width: 180px; + .zone-header{ + @include flex-center; + .value { + width: 100%; + text-align: start; + max-width: 180px; + } } .options-container { @@ -61,11 +62,18 @@ cursor: pointer; } } + &:first-child{ + background: var(--highlight-accent-color); + .input-value{ + color: var(--highlight-text-color); + } + } } - .active { background: var(--highlight-accent-color); - color: var(--primary-color); + .input-value{ + color: var(--highlight-text-color); + } } } diff --git a/app/src/styles/layout/sidebar.scss b/app/src/styles/layout/sidebar.scss index 01715ec..583dc0a 100644 --- a/app/src/styles/layout/sidebar.scss +++ b/app/src/styles/layout/sidebar.scss @@ -434,7 +434,7 @@ button { path { stroke: var(--accent-color); - strokeWidth: 1.5px; + stroke-width: 1.5px; } color: var(--accent-color); &:before { @@ -456,6 +456,9 @@ .sidebar-right-content-container { .dataSideBar { .inputs-wrapper { + display: flex; + flex-direction: column; + gap: 6px; .datas { .input-value { padding: 5px 10px; @@ -487,6 +490,7 @@ .datas__class { display: flex; align-items: center; + gap: 12px; .multi-level-dropdown { width: 170px; @@ -496,22 +500,13 @@ justify-content: space-between; gap: 6px; } - } - } - - .datas__class { - display: flex; - gap: 12px; - - // .datas__separator { - // } - - .disable { - cursor: not-allowed; - pointer-events: none; - /* Disables all mouse interactions */ - opacity: 0.5; - /* Optional: Makes the button look visually disabled */ + .disable { + cursor: not-allowed; + pointer-events: none; + /* Disables all mouse interactions */ + opacity: 0.5; + /* Optional: Makes the button look visually disabled */ + } } } } @@ -522,12 +517,6 @@ padding-bottom: 6px; } - .inputs-wrapper { - display: flex; - flex-direction: column; - gap: 6px; - } - .selectedMain-container { display: flex; flex-direction: column; @@ -627,10 +616,8 @@ width: 100%; height: 150px; background: #f0f0f0; - // border-radius: 8px; display: flex; align-items: center; - // justify-content: center; } .optionsContainer { @@ -713,7 +700,7 @@ path { stroke: var(--accent-color); - strokeWidth: 1.5px; + stroke-width: 1.5px; } &:hover { @@ -742,14 +729,14 @@ .add-button { @include flex-center; padding: 2px 4px; - background: var(--accent-color); - color: var(--primary-color); + background: var(--background-color-button); + color: var(--text-button-color); border-radius: #{$border-radius-small}; cursor: pointer; outline: none; border: none; path { - stroke: var(--primary-color); + stroke: var(--text-button-color); } &:disabled { background: var(--text-disabled); @@ -804,11 +791,10 @@ } .lists-main-container { - margin: 2px 8px; - width: calc(100% - 12px); - margin-right: 4px; + margin: 2px; + width: calc(100% - 4px); background: var(--background-color-gray); - border-radius: #{$border-radius-small}; + border-radius: 8px; min-height: 120px; .list-container { @@ -818,10 +804,10 @@ .list-item { @include flex-space-between; - padding: 2px 12px; + padding: 4px 12px; width: 100%; margin: 2px 0; - border-radius: #{$border-radius-small}; + border-radius: #{$border-radius-medium}; .value { display: flex; justify-content: flex-start; @@ -1156,7 +1142,13 @@ } .assets-container { - padding: 0 6px; + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: wrap; + height: 100%; + gap: 3px; + padding: 10px 0; .assets-wrapper { width: 100%; @@ -1175,14 +1167,16 @@ flex-direction: row; flex-wrap: wrap; height: 100%; - gap: 8px; + gap: 0px 4px; padding: 10px 0; .category { - width: 121px; + width: 123px; height: 95px; - border-radius: 3.59px; - background: var(--background-color-gray); + border-radius: #{$border-radius-large}; + background: var(--background-color); + outline: 1px solid var(--border-color); + outline-offset: -1px; padding: 8px; padding-top: 12px; font-weight: $bold-weight; @@ -1193,8 +1187,6 @@ position: relative; z-index: 3; font-size: var(--font-size-regular); - // -webkit-text-fill-color: transparent; - // -webkit-text-stroke: 1px black; } &::after { @@ -1260,7 +1252,6 @@ .category-image { position: absolute; - // top: 50%; bottom: 0; right: -10px; transform: translate(0, 0%) scale(0.8); @@ -1276,14 +1267,15 @@ flex-direction: row; flex-wrap: wrap; height: 100%; - gap: 3px; + gap: 0px 4px; padding: 10px 0; .assets { - width: 117px; + width: 123px; height: 95px; - border-radius: #{$border-radius-small}; - background: var(--background-color-gray); + border-radius: #{$border-radius-large}; + background: var(--background-color); + outline: 1px solid var(--border-color); font-weight: $medium-weight; position: relative; overflow: hidden; @@ -1301,18 +1293,16 @@ z-index: 3; padding: 8px; width: 100%; - max-height: 38px; + height: 100%; font-size: var(--font-size-regular); - background: color-mix( - in srgb, - var(--background-color) 40%, - transparent - ); - backdrop-filter: blur(5px); + background: linear-gradient(0deg,rgba(37, 24, 51, 0) 0%, rgba(78, 22, 128, 0.4) 100%); + pointer-events: none; + backdrop-filter: blur(8px); opacity: 0; transition: opacity 0.3s ease; display: -webkit-box; - -webkit-line-clamp: 2; + -webkit-line-clamp: 3; + line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; @@ -1337,46 +1327,6 @@ } } -.assets-container { - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: wrap; - height: 100%; - gap: 3px; - padding: 10px 0; - - .assets { - width: 117px; - height: 95px; - border-radius: 3.59px; - background: var(--background-color-gray); - padding: 8px; - padding-top: 12px; - font-weight: $medium-weight; - position: relative; - overflow: hidden; - - .asset-name { - position: relative; - z-index: 3; - font-size: var(--font-size-regular); - } - - .asset-image { - height: 100%; - width: 100%; - position: absolute; - // top: 50%; - // right: 5px; - // transform: translate(0, -50%); - top: 0; - left: 0; - z-index: 2; - } - } -} - .assets-result { width: 100%; height: 100%;