Add tooltips to various components and improve styling for better user experience

This commit is contained in:
Vishnu 2025-05-07 13:56:31 +05:30
parent b26a0cd6cd
commit ad2b6b96f3
15 changed files with 174 additions and 73 deletions

View File

@ -66,6 +66,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => setSubModule("properties")}
>
<div className="tooltip">properties</div>
<PropertiesIcon isActive={subModule === "properties"} />
</button>
)}
@ -77,6 +78,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => setSubModule("simulations")}
>
<div className="tooltip">simulations</div>
<SimulationIcon isActive={subModule === "simulations"} />
</button>
<button
@ -85,6 +87,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => setSubModule("mechanics")}
>
<div className="tooltip">mechanics</div>
<MechanicsIcon isActive={subModule === "mechanics"} />
</button>
<button
@ -93,6 +96,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => setSubModule("analysis")}
>
<div className="tooltip">analysis</div>
<AnalysisIcon isActive={subModule === "analysis"} />
</button>
</>

View File

@ -126,29 +126,31 @@ const CollaborationPopup: React.FC<CollaborateProps> = ({
<MultiEmailInvite />
</div>
<div className="split"></div>
<div className="access-and-user-control-container">
<div className="user-header">Who has access</div>
<div className="general-access-container">
<div className="team-container">
<div className="project-name">Untitled</div>
<div className="number-of-peoples-have-access">
{users.length} persons
<section>
<div className="access-and-user-control-container">
<div className="user-header">Who has access</div>
<div className="general-access-container">
<div className="team-container">
<div className="project-name">Untitled</div>
<div className="number-of-peoples-have-access">
{users.length} persons
</div>
</div>
</div>
</div>
<div className="users-list-container">
<div className="you-container">
<div className="your-name">
<div className="user-profile">{userName[0]}</div>
{userName}
<div className="users-list-container">
<div className="you-container">
<div className="your-name">
<div className="user-profile">{userName[0]}</div>
{userName}
</div>
<div className="indicater">you</div>
</div>
<div className="indicater">you</div>
{users.map((user, index) => (
<UserListTemplate key={index} user={user} />
))}
</div>
{users.map((user, index) => (
<UserListTemplate key={index} user={user} />
))}
</div>
</div>
</section>
</div>
</div>
</RenderOverlay>

View File

@ -218,6 +218,7 @@ const Tools: React.FC = () => {
setActiveTool("cursor");
}}
>
<div className="tooltip">cursor</div>
<CursorIcon isActive={activeTool === "cursor"} />
</div>
)}
@ -230,6 +231,7 @@ const Tools: React.FC = () => {
setActiveTool("free-hand");
}}
>
<div className="tooltip">free hand</div>
<FreeMoveIcon isActive={activeTool === "free-hand"} />
</div>
)}
@ -242,6 +244,7 @@ const Tools: React.FC = () => {
setActiveTool("delete");
}}
>
<div className="tooltip">delete</div>
<DeleteIcon isActive={activeTool === "delete"} />
</div>
)}
@ -315,8 +318,8 @@ const Tools: React.FC = () => {
onClick={() => {
setActiveTool("draw-wall");
}}
title="Wall"
>
<div className="tooltip">draw wall</div>
<WallIcon isActive={activeTool === "draw-wall"} />
</div>
<div
@ -326,8 +329,8 @@ const Tools: React.FC = () => {
onClick={() => {
setActiveTool("draw-zone");
}}
title="Zone"
>
<div className="tooltip">draw zone</div>
<ZoneIcon isActive={activeTool === "draw-zone"} />
</div>
<div
@ -337,8 +340,8 @@ const Tools: React.FC = () => {
onClick={() => {
setActiveTool("draw-aisle");
}}
title="Aisle"
>
<div className="tooltip">draw asile</div>
<AsileIcon isActive={activeTool === "draw-aisle"} />
</div>
<div
@ -348,8 +351,8 @@ const Tools: React.FC = () => {
onClick={() => {
setActiveTool("draw-floor");
}}
title="Floor"
>
<div className="tooltip">draw floor</div>
<FloorIcon isActive={activeTool === "draw-floor"} />
</div>
</div>
@ -366,8 +369,8 @@ const Tools: React.FC = () => {
onClick={() => {
setActiveTool("measure");
}}
title="Measure"
>
<div className="tooltip">measure scale</div>
<MeasureToolIcon isActive={activeTool === "measure"} />
</div>
</div>
@ -385,6 +388,7 @@ const Tools: React.FC = () => {
setActiveTool("pen");
}}
>
<div className="tooltip">pen</div>
<PenIcon isActive={activeTool === "pen"} />
</div>
</div>
@ -407,6 +411,7 @@ const Tools: React.FC = () => {
});
}}
>
<div className="tooltip">save template</div>
<SaveTemplateIcon isActive={false} />
</div>
</div>
@ -422,6 +427,7 @@ const Tools: React.FC = () => {
setActiveTool("comment");
}}
>
<div className="tooltip">comment</div>
<CommentIcon isActive={activeTool === "comment"} />
</div>
{toggleThreeD && (
@ -433,6 +439,7 @@ const Tools: React.FC = () => {
setIsPlaying(!isPlaying);
}}
>
<div className="tooltip">play</div>
<PlayIcon isActive={activeTool === "play"} />
</div>
)}
@ -446,6 +453,7 @@ const Tools: React.FC = () => {
}`}
onClick={toggleSwitch}
>
<div className="tooltip">toggle view</div>
<div
className={`toggle-option${!toggleThreeD ? " active" : ""}`}
>

View File

@ -128,16 +128,16 @@ const ROISummary = ({
</div>
<div
className={`metric-item net-profit ${
roiSummaryData.netLoss ?? "loss"
roiSummaryData.netProfit ?? "loss"
}`}
>
>
<div className="metric-label">
<span></span>
Net Profit
</div>
<div className="metric-value">
<span></span>
{roiSummaryData.netProfit}
{roiSummaryData.netProfit ? roiSummaryData.netProfit : roiSummaryData.netLoss}
</div>
</div>
</div>

View File

@ -16,7 +16,7 @@ const ProductionCapacity = ({
const partialFillPercent =
((progressPercent / 100) * totalBars - barsToFill) * 100;
const isLoading = false;
const isLoading = true;
return (
<div className="throughtputSummary-container analysis-card">
<div className="throughtputSummary-wrapper analysis-card-wrapper">

View File

@ -14,8 +14,6 @@ import {
useZones,
useZonePoints,
} from "../../../store/store";
// import { setZonesApi } from "../../../services/factoryBuilder/zones/setZonesApi";
// import { deleteZonesApi } from "../../../services/factoryBuilder/zones/deleteZoneApi";
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
import * as CONSTANTS from "../../../types/world/worldConstants";
@ -37,10 +35,10 @@ const ZoneGroup: React.FC = () => {
const { toggleView } = useToggleView();
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
const { removedLayer, setRemovedLayer } = useRemovedLayer();
const { toolMode, setToolMode } = useToolMode();
const { toolMode } = useToolMode();
const { movePoint, setMovePoint } = useMovePoint();
const { deleteTool, setDeleteTool } = useDeleteTool();
const { activeLayer, setActiveLayer } = useActiveLayer();
const { setDeleteTool } = useDeleteTool();
const { activeLayer } = useActiveLayer();
const { socket } = useSocketStore();
const groupsRef = useRef<any>();
@ -204,6 +202,7 @@ const ZoneGroup: React.FC = () => {
socket.emit("v2:zone:set", input);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
const updateZoneToBackend = async (zone: {
zoneId: string;
zoneName: string;
@ -271,6 +270,7 @@ const ZoneGroup: React.FC = () => {
socket.emit("v2:zone:delete", input);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
const handleDeleteZone = (zoneId: string) => {
const updatedZones = zones.filter((zone: any) => zone.zoneId !== zoneId);
setZones(updatedZones);
@ -290,7 +290,6 @@ const ZoneGroup: React.FC = () => {
);
setZonePoints(updatedzonePoints);
}
deleteZoneFromBackend(zoneId);
};
@ -526,11 +525,12 @@ const ZoneGroup: React.FC = () => {
setEndPoint(point);
}
});
return (
<group ref={groupsRef} name="zoneGroup">
<group name="zones" visible={!toggleView}>
{zones.map((zone: any) => (
<group key={zone.zoneId} name={zone.zoneName}>
<group key={zone.zoneId} name={zone.zoneName} visible={false}>
{zone.points
.slice(0, -1)
.map((point: [number, number, number], index: number) => {
@ -563,7 +563,6 @@ const ZoneGroup: React.FC = () => {
key={index}
position={midpoint}
rotation={[0, -angle, 0]}
visible={false}
>
<planeGeometry args={[planeWidth, planeHeight]} />
<primitive

View File

@ -130,7 +130,6 @@ const RealTimeVisulization: React.FC = () => {
});
}, [selectedZone]);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
const editWidgetOptions = document.querySelector(
@ -179,12 +178,22 @@ const RealTimeVisulization: React.FC = () => {
<style>
{`
:root {
--realTimeViz-container-width: ${canvasDimensions.width}px;
--realTimeViz-container-height: ${canvasDimensions.height}px;
--realTimeViz-container-width: ${canvasDimensions.width};
--realTimeViz-container-height: ${canvasDimensions.height};
}
`}
</style>
<div ref={containerRef} className="realTime-viz">
<div
ref={containerRef}
className="realTime-viz"
style={{
height: isPlaying || activeModule !== "visualization" ? "100vh" : "",
width: isPlaying || activeModule !== "visualization" ? "100vw" : "",
left: isPlaying || activeModule !== "visualization" ? "0%" : "",
borderRadius:
isPlaying || activeModule !== "visualization" ? "" : "6px",
}}
>
<div className="realTime-viz-wrapper">
{openConfirmationPopup && (
<RenderOverlay>

View File

@ -558,7 +558,7 @@ const DroppedObjects: React.FC = () => {
return (
<div
key={obj.id}
key={`${obj.id}-${index}`}
className={`${obj.className} ${
selectedChartId?.id === obj.id && "activeChart"
} `}

View File

@ -28,3 +28,29 @@ section,
border: none;
}
}
.tooltip {
position: absolute;
top: calc(-100% - 8px);
background: var(--background-color-solid);
padding: 4px 10px;
border-radius: #{$border-radius-medium};
color: var(--text-color);
pointer-events: none;
user-select: none;
transition: all 0.3s;
opacity: 0;
text-transform: capitalize;
white-space: nowrap;
&::after {
content: "";
position: absolute;
height: 6px;
width: 6px;
background: var(--background-color-solid);
z-index: -1;
bottom: 0;
left: 50%;
transform: translate(-50%, 50%) rotate(45deg);
}
}

View File

@ -667,13 +667,13 @@ input[type="number"] {
padding: 2px 8px;
border-radius: #{$border-radius-large};
flex-wrap: wrap;
max-height: 180px;
overflow: auto;
input {
border: none;
outline: none;
background: transparent;
width: 100%;
&::placeholder {
color: var(--text-disabled);

View File

@ -376,11 +376,9 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.metric-label.loss {
background: #6D4343;
border: 1px solid #FF301D
span{
margin-right: 4px;
}
}
.metric-value {
@ -390,12 +388,11 @@
}
.metric-item.loss {
background: #6D4343;
background: #ff301d48;
border: 1px solid #FF301D;
.metric-label {
span {
color: #FF311E;
color: #ff7a6e;
display: inline-block;
transform: rotate(180deg);
}

View File

@ -44,6 +44,7 @@
width: 28px;
cursor: pointer;
border-radius: #{$border-radius-medium};
position: relative;
&:hover {
background: color-mix(
@ -51,6 +52,10 @@
var(--highlight-accent-color) 60%,
transparent
);
.tooltip {
opacity: 1;
transform: translateY(-2px);
}
}
}
@ -135,11 +140,19 @@
gap: 5px;
position: relative;
&:hover {
.tooltip {
opacity: 1;
transform: translateY(-4px);
}
}
.toggle-option {
font-size: var(--font-size-small);
padding: 2px;
z-index: 1;
transition: all 0.2s;
pointer-events: none;
}
&::after {
@ -152,6 +165,7 @@
width: 23px;
border-radius: #{$border-radius-medium};
transition: all 0.2s;
pointer-events: none;
}
.active {

View File

@ -11,18 +11,18 @@
width: 520px;
background: var(--background-color);
border-radius: #{$border-radius-large};
backdrop-filter: blur(8px);
.split {
width: 100%;
height: 1px;
background: var(--highlight-accent-color);
backdrop-filter: blur(15px);
outline: 1px solid var(--border-color);
padding: 6px;
section{
margin: 0;
}
.header {
@include flex-space-between;
padding: 12px;
border-bottom: 1px solid var(--border-color);
.content {
@include flex-center;
gap: 8px;
.copy-link-button {
font-size: var(--font-size-small);
&:hover {
@ -49,6 +49,8 @@
}
.access-and-user-control-container {
padding: 12px;
max-height: 50vh;
overflow: auto;
.user-header {
margin-bottom: 12px;
}
@ -58,7 +60,7 @@
.team-container,
.you-container {
@include flex-space-between;
padding: 8px 12px;
padding: 8px;
.user-details {
@include flex-center;
gap: 8px;
@ -113,10 +115,6 @@
outline-offset: -1px;
}
}
.team-container,
.you-container {
border-top: 1px solid var(--border-color);
}
}
}
}

View File

@ -376,6 +376,15 @@
background: transparent;
overflow: visible;
.tooltip {
top: 6px;
right: calc(100% + 6px);
&::after{
left: 100%;
bottom: 50%;
}
}
.sidebar-action-list {
margin-bottom: 12px;
@include flex-center;
@ -386,11 +395,30 @@
backdrop-filter: blur(12px);
outline: 1px solid var(--border-color);
outline-offset: -1px;
transition: all 0.2s;
&:hover {
outline-color: var(--border-color-accent);
svg{
transition: all .2s;
scale: 1.1;
}
.tooltip {
opacity: 1;
transform: translateX(-2px);
}
}
}
.active {
background: var(--background-color-accent);
outline: none;
&:hover {
svg{
scale: 1;
}
background: var(--background-color-accent);
}
}
}
@ -1199,9 +1227,7 @@
flex-direction: row;
flex-wrap: wrap;
height: 100%;
max-height: 50vh;
gap: 3px;
overflow: auto;
.assets-result {
width: 100%;
@ -1219,6 +1245,8 @@
.assets-wrapper {
width: 100%;
position: relative;
max-height: 50vh;
overflow: auto;
h2,
.searched-content {
@ -1255,6 +1283,19 @@
position: relative;
overflow: hidden;
&:hover {
outline: 1px solid var(--border-color-accent);
img {
transition: all 0.2s;
scale: 1.3;
}
&::after {
top: 80px;
right: 0;
scale: 2;
}
}
.category-name {
position: relative;
z-index: 3;
@ -1266,12 +1307,12 @@
width: 60px;
height: 60px;
border-radius: #{$border-radius-circle};
background: var(--circle-color, #000);
position: absolute;
top: 60%;
right: -10px;
transform: translate(0, -50%);
transition: all 0.2s ease-in-out;
}
&:nth-child(1),
@ -1358,6 +1399,9 @@
.asset-name {
opacity: 1;
}
.asset-image {
scale: 1.2;
}
}
.asset-name {
@ -1368,9 +1412,11 @@
width: 100%;
height: 100%;
font-size: var(--font-size-regular);
background: linear-gradient(0deg,
rgba(37, 24, 51, 0) 0%,
rgba(78, 22, 128, 0.4) 100%);
background: linear-gradient(
0deg,
rgba(37, 24, 51, 0) 0%,
rgba(52, 41, 61, 0.5) 100%
);
pointer-events: none;
backdrop-filter: blur(8px);
opacity: 0;
@ -1388,13 +1434,13 @@
width: 100%;
z-index: 2;
object-fit: cover;
transition: all 0.2s;
}
}
}
}
}
.skeleton-wrapper {
display: flex;
.asset-name {
@ -1407,9 +1453,6 @@
}
}
.sidebar-left-wrapper,
.sidebar-right-wrapper {
height: calc(50vh + 150px);

View File

@ -21,10 +21,11 @@
}
.floating {
width: calc(var(--realTimeViz-container-width) * 0.2);
height: calc(var(--realTimeViz-container-width) * 0.05);
width: calc(var(--realTimeViz-container-width) * 0.2px);
min-width: 250px;
transform: scale(min(1, calc(var(--realTimeViz-container-width) / 1000)));
min-width: 230px;
max-width: 300px;
background: var(--background-color);