Merge remote-tracking branch 'origin/main-demo-ui' into main-dev

This commit is contained in:
2025-12-17 10:44:42 +05:30
14 changed files with 1681 additions and 816 deletions

52
app/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "aalai-beta",
"version": "0.1.0",
"version": "0.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "aalai-beta",
"version": "0.1.0",
"version": "0.1.1",
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
@@ -2031,7 +2031,7 @@
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"devOptional": true,
"dev": true,
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
@@ -2043,7 +2043,7 @@
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"devOptional": true,
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -4242,26 +4242,6 @@
"url": "https://github.com/sponsors/gregberge"
}
},
"node_modules/@testing-library/dom": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
"@types/aria-query": "^5.0.1",
"aria-query": "5.3.0",
"dom-accessibility-api": "^0.5.9",
"lz-string": "^1.5.0",
"picocolors": "1.1.1",
"pretty-format": "^27.0.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@testing-library/jest-dom": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
@@ -4373,25 +4353,25 @@
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"devOptional": true
"dev": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"devOptional": true
"dev": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"devOptional": true
"dev": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"devOptional": true
"dev": true
},
"node_modules/@turf/along": {
"version": "7.2.0",
@@ -9233,7 +9213,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"devOptional": true
"dev": true
},
"node_modules/cross-env": {
"version": "7.0.3",
@@ -10249,7 +10229,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=0.3.1"
}
@@ -15652,7 +15632,7 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"devOptional": true
"dev": true
},
"node_modules/makeerror": {
"version": "1.0.12",
@@ -21308,7 +21288,7 @@
"version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"devOptional": true,
"dev": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -21351,7 +21331,7 @@
"version": "8.3.4",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
"devOptional": true,
"dev": true,
"dependencies": {
"acorn": "^8.11.0"
},
@@ -21363,7 +21343,7 @@
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"devOptional": true
"dev": true
},
"node_modules/tsconfig-paths": {
"version": "3.15.0",
@@ -21859,7 +21839,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"devOptional": true
"dev": true
},
"node_modules/v8-to-istanbul": {
"version": "8.1.1",
@@ -22952,7 +22932,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=6"
}

View File

@@ -1,6 +1,6 @@
{
"name": "aalai-beta",
"version": "0.1.0",
"version": "0.1.1",
"private": true,
"dependencies": {
"@dnd-kit/core": "^6.3.1",
@@ -56,7 +56,7 @@
"prepare": "husky",
"prestart": "tsc scripts/git-prompt.ts && node scripts/git-prompt.js",
"start": "react-scripts start",
"build": "GENERATE_SOURCEMAP=false react-scripts build",
"build": "cross-env GENERATE_SOURCEMAP=false react-scripts build",
"test": "jest"
},
"eslintConfig": {

View File

@@ -1,21 +1,39 @@
import { getUserData } from "../../functions/getUserData";
import { ALPHA_ORG } from "../../pages/Dashboard";
import { DeleteIcon } from "../icons/ContextMenuIcons";
import RenameInput from "../ui/inputs/RenameInput";
export const TutorialCard: React.FC<{ tutorial: Tutorial; onClick: (tutorial: Tutorial) => void }> = ({ tutorial, onClick }) => {
export const TutorialCard: React.FC<{
tutorial: Tutorial;
onClick: (tutorial: Tutorial) => void;
}> = ({ tutorial, onClick }) => {
const { organization } = getUserData();
return (
<div className="tutorial-card-container" onClick={() => onClick(tutorial)}>
<div
className="preview-container"
style={{
backgroundImage: tutorial.thumbnail ? `url(${tutorial.thumbnail})` : "linear-gradient(135deg, #ddd, #bbb)",
backgroundImage: tutorial.thumbnail
? `url(${tutorial.thumbnail})`
: "linear-gradient(135deg, #ddd, #bbb)",
}}
></div>
<div className="tutorial-details">
<div
className="tutorial-details"
onClick={(e) => {
e.stopPropagation();
}}
>
<div className="context">
<div className="tutorial-name">{tutorial.projectName}</div>
<div className="updated-date">{new Date(tutorial.createdAt).toLocaleDateString()}</div>
<div className="tutorial-name">
<RenameInput
value={tutorial.projectName}
canEdit={organization === ALPHA_ORG}
/>
</div>
<div className="updated-date">
{new Date(tutorial.createdAt).toLocaleDateString()}
</div>
</div>
{organization === ALPHA_ORG && (
<div className="delete-option">

View File

@@ -1,4 +1,4 @@
import type { RefObject } from "react";
import { useState, type RefObject } from "react";
import { Block } from "../../../../types/exportedTypes";
import { getAlphaFromRgba, rgbaToHex } from "../../functions/helpers/colorHandlers";
import { getCurrentBlockStyleValue } from "../../functions/helpers/getCurrentBlockStyleValue";
@@ -8,6 +8,11 @@ import { handleBlurAmountChange } from "../../functions/helpers/handleBlurAmount
import InputRange from "../../../ui/inputs/InputRange";
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
import { DeleteIcon } from "../../../icons/ContextMenuIcons";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
import { AddIcon, DeviceIcon, ParametersIcon } from "../../../icons/ExportCommonIcons";
import DataDetailedDropdown from "../../../ui/inputs/DataDetailedDropdown";
import RenameInput from "../../../ui/inputs/RenameInput";
import DataSourceSelector from "../../../ui/inputs/DataSourceSelector";
interface BlockEditorProps {
blockEditorRef: RefObject<HTMLDivElement>;
@@ -32,6 +37,10 @@ const BlockEditor: React.FC<BlockEditorProps> = ({
updateBlockZIndex,
handleRemoveBlock,
}) => {
const [color, setColor] = useState("#000000");
return (
<div ref={blockEditorRef} className="panel block-editor-panel">
<div className="header">
@@ -45,219 +54,158 @@ const BlockEditor: React.FC<BlockEditorProps> = ({
<DeleteIcon />
</div>
</div>
<div className="form-group">
<label className="form-label">Position Type: </label>
<select
value={currentBlock.positionType || "relative"}
onChange={(e) => updateBlockPositionType(selectedBlock, e.target.value as "relative" | "absolute" | "fixed")}
className="form-select"
>
<option value="relative">Relative</option>
<option value="absolute">Absolute</option>
<option value="fixed">Fixed</option>
</select>
{/* <RegularDropDown
header={currentBlock.positionType || "relative"}
options={["Relative", "Absolute", "Fixed"]} // Pass layout names as options
onSelect={(option) => updateBlockPositionType(
selectedBlock,
option.toLowerCase() as "relative" | "absolute" | "fixed"
)}
search={false}
/> */}
</div>
{currentBlock.positionType === "absolute" && (
<>
<div className="form-group">
<label className="form-label">X Position: </label>
<input
type="number"
placeholder="X"
value={currentBlock.position?.x || 0}
onChange={(e) =>
updateBlockPosition(selectedBlock, {
...currentBlock.position!,
x: Number(e.target.value),
})
}
className="form-input"
/>
<div className="design-section-wrapper">
<div className="design-section">
<div className="section-header">Size</div>
<InputWithDropDown
label="Width"
value={String(currentBlock.size?.width || 400)} // Ensure the value is a string
placeholder={"Width"}
onChange={(newValue) => {
updateBlockSize(selectedBlock, {
...currentBlock.size!,
width: Number(newValue), // Make sure to convert the string back to a number here
})
}}
/>
<InputWithDropDown
label="Height"
value={String(currentBlock.size?.height || 300)}
placeholder={"Width"}
onChange={(newValue) => {
updateBlockSize(selectedBlock, {
...currentBlock.size!,
height: Number(newValue),
})
}}
/>
</div>
<div className="design-section">
<div className="section-header">Position</div>
<div className="select-type">
{["relative", "absolute"].map((position) => (
<div
key={position}
className={`type ${currentBlock.positionType === position ? "active" : ""}`}
onClick={() => updateBlockPositionType(selectedBlock, position as "relative" | "absolute" | "fixed")}
>
{position.charAt(0).toUpperCase() + position.slice(1)}
</div>
))}
</div>
<div className="form-group">
<label className="form-label">Y Position: </label>
<input
type="number"
placeholder="Y"
value={currentBlock.position?.y || 0}
onChange={(e) =>
updateBlockPosition(selectedBlock, {
...currentBlock.position!,
y: Number(e.target.value),
})
}
className="form-input"
/>
<div className="position-canvas">
<div className="canvas">
<div className="value padding-top">
<RenameInput
value={
getCurrentBlockStyleValue(currentBlock, "padding")
? String(getCurrentBlockStyleValue(currentBlock, "padding"))
: "120"
}
/>
</div>
<div className="value padding-right">
<RenameInput
value={
getCurrentBlockStyleValue(currentBlock, "padding")
? String(getCurrentBlockStyleValue(currentBlock, "padding"))
: "120"
}
/>
</div>
<div className="value padding-bottom">
<RenameInput
value={
getCurrentBlockStyleValue(currentBlock, "padding")
? String(getCurrentBlockStyleValue(currentBlock, "padding"))
: "120"
}
/>
</div>
<div className="value padding-left">
<RenameInput
value={
getCurrentBlockStyleValue(currentBlock, "padding")
? String(getCurrentBlockStyleValue(currentBlock, "padding"))
: "120"
}
/>
</div>
</div>
</div>
</>
)}
<div className="form-group">
<label className="form-label">Background Color: </label>
<input
type="color"
value={rgbaToHex(getCurrentBlockStyleValue(currentBlock, "backgroundColor"))}
onChange={(e) => handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, e.target.value)}
className="color-input"
/>
<div className="design-section-footer">
<InputWithDropDown
label="Layer"
value={String(currentBlock.zIndex || 1)}
placeholder={"Layer"}
onChange={(newValue) => updateBlockZIndex(selectedBlock, Number(newValue))}
/>
<InputRange
label={"Radius"}
min={0}
max={8}
value={parseInt(getCurrentBlockStyleValue(currentBlock, "borderRadius")) || 8}
onChange={(newValue) => {
updateBlockStyle(selectedBlock, {
borderRadius: Number(newValue),
})
}}
/>
</div>
</div>
<div className="design-section">
<div className="section-header">Background</div>
<div className="data-picker">
<div className="label">Color</div>
<div className="left">
<input
type="color"
value={rgbaToHex(getCurrentBlockStyleValue(currentBlock, "backgroundColor"))}
// onChange={(e) => setColor(e.target.value)}
onChange={(e) => handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, e.target.value)}
/>
<div className="colorValue">{color}</div>
</div>
</div>
<InputRange
label={"Opacity"}
min={0}
max={8}
value={Math.round(getAlphaFromRgba(getCurrentBlockStyleValue(currentBlock, "backgroundColor")) * 100)}
// onChange={(value: number) => handleBackgroundAlphaChange(currentBlock, selectedBlock, updateBlockStyle, Number(value))}
onChange={(value: number) => handleBlurAmountChange(selectedBlock, updateBlockStyle, Number(value))}
/>
<InputRange
label={"Blur"}
min={0}
max={8}
value={parseInt(getCurrentBlockStyleValue(currentBlock, "backdropFilter")?.match(/\d+/)?.[0] || "10")}
/>
</div>
</div>
<div className="form-group">
{/* <label className="form-label">
Background Opacity:{" "}
{Math.round(
getAlphaFromRgba(
getCurrentBlockStyleValue(currentBlock, "backgroundColor")
) * 100
)}
%
</label>
<input
type="range"
min="0"
max="100"
value={
getAlphaFromRgba(
getCurrentBlockStyleValue(currentBlock, "backgroundColor")
) * 100
}
onChange={(e) =>
handleBackgroundAlphaChange(
currentBlock,
selectedBlock,
updateBlockStyle,
Number(e.target.value)
)
}
className="range-input"
/> */}
<InputRange
label="Background Opacity"
disabled={false}
value={Math.round(getAlphaFromRgba(getCurrentBlockStyleValue(currentBlock, "backgroundColor")) * 100)}
min={0}
max={100}
onChange={(value: number) => handleBackgroundAlphaChange(currentBlock, selectedBlock, updateBlockStyle, Number(value))}
// onPointerUp={updatedDist}
key={"6"}
/>
</div>
<div className="form-group">
{/* <label className="form-label">
Blur Amount:{" "}
{parseInt(
getCurrentBlockStyleValue(currentBlock, "backdropFilter")?.match(
/\d+/
)?.[0] || "10"
)}
px
</label>
<input
type="range"
min="0"
max="50"
value={parseInt(
getCurrentBlockStyleValue(currentBlock, "backdropFilter")?.match(
/\d+/
)?.[0] || "10"
)}
onChange={(e) =>
handleBlurAmountChange(
selectedBlock,
updateBlockStyle,
Number(e.target.value)
)
}
className="range-input"
/> */}
<InputRange
label="Blur Amount"
disabled={false}
value={parseInt(getCurrentBlockStyleValue(currentBlock, "backdropFilter")?.match(/\d+/)?.[0] || "10")}
min={0}
max={50}
onChange={(value: number) => handleBlurAmountChange(selectedBlock, updateBlockStyle, Number(value))}
// onPointerUp={updatedDist}
key={"6"}
/>
</div>
<div className="form-group">
<label className="form-label">Width: </label>
<input
type="number"
placeholder="Width"
value={currentBlock.size?.width || 400}
onChange={(e) =>
updateBlockSize(selectedBlock, {
...currentBlock.size!,
width: Number(e.target.value),
})
}
className="form-input"
/>
</div>
<div className="form-group">
<label className="form-label">Height: </label>
<input
type="number"
placeholder="Height"
value={currentBlock.size?.height || 300}
onChange={(e) =>
updateBlockSize(selectedBlock, {
...currentBlock.size!,
height: Number(e.target.value),
})
}
className="form-input"
/>
</div>
<div className="form-group">
<label className="form-label">Z-Index: </label>
<input type="number" placeholder="Z-Index" value={currentBlock.zIndex || 1} onChange={(e) => updateBlockZIndex(selectedBlock, Number(e.target.value))} className="form-input" />
</div>
<div className="form-group">
<label className="form-label">Padding: </label>
<input
type="number"
placeholder="Padding"
value={parseInt(getCurrentBlockStyleValue(currentBlock, "padding")) || 10}
onChange={(e) => updateBlockStyle(selectedBlock, { padding: Number(e.target.value) })}
className="form-input"
/>
</div>
<div className="form-group">
<label className="form-label">Border Radius: </label>
<input
type="number"
placeholder="Border Radius"
value={parseInt(getCurrentBlockStyleValue(currentBlock, "borderRadius")) || 8}
onChange={(e) =>
updateBlockStyle(selectedBlock, {
borderRadius: Number(e.target.value),
})
}
className="form-input"
/>
</div>
</div>
);
};

View File

@@ -1748,3 +1748,118 @@ export const PerformanceStatsIcon = () => {
</svg>
);
};
export const DeviceIcon = () => {
return (
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.4 1.125H5.38395C4.97753 1.125 4.64972 1.125 4.38427 1.14668C4.11095 1.16902 3.87088 1.2162 3.64877 1.32937C3.29597 1.50913 3.00913 1.79597 2.82937 2.14877C2.7162 2.37088 2.66902 2.61095 2.64668 2.88427C2.625 3.14972 2.625 3.47753 2.625 3.88395V3.9V8.1V8.11605C2.625 8.52245 2.625 8.8503 2.64668 9.11575C2.66902 9.38905 2.7162 9.6291 2.82937 9.85125C3.00913 10.2041 3.29597 10.4908 3.64877 10.6706C3.87088 10.7838 4.11095 10.831 4.38427 10.8533C4.64972 10.875 4.97753 10.875 5.38395 10.875H5.4H6.6H6.61605C7.0225 10.875 7.3503 10.875 7.61575 10.8533C7.88905 10.831 8.1291 10.7838 8.35125 10.6706C8.70405 10.4908 8.99085 10.2041 9.17065 9.85125C9.2838 9.6291 9.331 9.38905 9.3533 9.11575C9.375 8.8503 9.375 8.5225 9.375 8.11605V8.1V3.9V3.88394C9.375 3.47753 9.375 3.14972 9.3533 2.88427C9.331 2.61095 9.2838 2.37088 9.17065 2.14877C8.99085 1.79597 8.70405 1.50913 8.35125 1.32937C8.1291 1.2162 7.88905 1.16902 7.61575 1.14668C7.3503 1.125 7.0225 1.125 6.61605 1.125H6.6H5.4ZM3.98926 1.99762C4.08802 1.9473 4.2184 1.91274 4.44534 1.89419C4.67666 1.87529 4.97378 1.875 5.4 1.875H6.6C7.02625 1.875 7.32335 1.87529 7.55465 1.89419C7.7816 1.91274 7.912 1.9473 8.01075 1.99762C8.2224 2.10548 8.3945 2.27758 8.5024 2.48926C8.5527 2.58802 8.58725 2.71841 8.6058 2.94534C8.6247 3.17666 8.625 3.47378 8.625 3.9V8.1C8.625 8.52625 8.6247 8.82335 8.6058 9.05465C8.58725 9.2816 8.5527 9.412 8.5024 9.51075C8.3945 9.7224 8.2224 9.8945 8.01075 10.0024C7.912 10.0527 7.7816 10.0872 7.55465 10.1058C7.32335 10.1247 7.02625 10.125 6.6 10.125H5.4C4.97378 10.125 4.67666 10.1247 4.44534 10.1058C4.2184 10.0872 4.08802 10.0527 3.98926 10.0024C3.77758 9.8945 3.60548 9.7224 3.49762 9.51075C3.4473 9.412 3.41274 9.2816 3.39419 9.05465C3.37529 8.82335 3.375 8.52625 3.375 8.1V3.9C3.375 3.47378 3.37529 3.17666 3.39419 2.94534C3.41274 2.71841 3.4473 2.58802 3.49762 2.48926C3.60548 2.27758 3.77758 2.10548 3.98926 1.99762ZM5 8.625C4.7929 8.625 4.625 8.7929 4.625 9C4.625 9.2071 4.7929 9.375 5 9.375H7C7.2071 9.375 7.375 9.2071 7.375 9C7.375 8.7929 7.2071 8.625 7 8.625H5Z" fill="#CCACFF" />
</svg>
);
};
export const ParametersIcon = () => {
return (
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_6422_4175)">
<path d="M10.5 4.875V3C10.4998 2.80116 10.4207 2.61052 10.2801 2.46992C10.1395 2.32932 9.94884 2.25023 9.75 2.25H8.625V3H9.75V4.875C9.75072 5.08872 9.79738 5.29978 9.88681 5.49388C9.97625 5.68799 10.1064 5.86059 10.2684 6C10.1064 6.13941 9.97625 6.31201 9.88681 6.50612C9.79738 6.70022 9.75072 6.91128 9.75 7.125V9H8.625V9.75H9.75C9.94884 9.74977 10.1395 9.67068 10.2801 9.53008C10.4207 9.38948 10.4998 9.19884 10.5 9V7.125C10.5002 6.92616 10.5793 6.73552 10.7199 6.59492C10.8605 6.45432 11.0512 6.37523 11.25 6.375V5.625C11.0512 5.62477 10.8605 5.54568 10.7199 5.40508C10.5793 5.26447 10.5002 5.07384 10.5 4.875Z" fill="#B7B7C6" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.375 3.375L6.05362 4.5H6.80362L7.125 3.375H7.875L7.55362 4.5H8.25V5.25H7.3395L6.91088 6.75H7.875V7.5H6.69638L6.375 8.625H5.625L5.94638 7.5H5.19638L4.875 8.625H4.125L4.44638 7.5H3.75V6.75H4.66087L5.0895 5.25H4.125V4.5H5.30362L5.625 3.375H6.375ZM6.5895 5.25H5.8395L5.41087 6.75H6.16088L6.5895 5.25Z" fill="#B7B7C6" />
<path d="M2.25 4.875V3H3.375V2.25H2.25C2.05116 2.25023 1.86052 2.32932 1.71992 2.46992C1.57932 2.61052 1.50023 2.80116 1.5 3V4.875C1.49977 5.07384 1.42068 5.26447 1.28008 5.40508C1.13948 5.54568 0.948842 5.62477 0.75 5.625V6.375C0.948842 6.37523 1.13948 6.45432 1.28008 6.59492C1.42068 6.73552 1.49977 6.92616 1.5 7.125V9C1.50023 9.19884 1.57932 9.38948 1.71992 9.53008C1.86052 9.67068 2.05116 9.74977 2.25 9.75H3.375V9H2.25V7.125C2.24928 6.91128 2.20262 6.70022 2.11319 6.50612C2.02375 6.31201 1.89363 6.13941 1.73164 6C1.89363 5.86059 2.02375 5.68799 2.11319 5.49388C2.20262 5.29978 2.24928 5.08872 2.25 4.875Z" fill="#B7B7C6" />
</g>
<defs>
<clipPath id="clip0_6422_4175">
<rect width="12" height="12" fill="white" />
</clipPath>
</defs>
</svg>
);
};
export const AlignRightIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 10H8M21 14H3M21 18H8M21 6H3" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
);
};
export const AlignJustifyIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 10H21M3 14H21M3 18H21M3 6H21" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
);
};
export const AlignLeftIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 10H16M3 14H21M3 18H16M3 6H21" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
);
};
export const FlexRowIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.1782 5.79502L13.1782 18.2059C13.1782 19.3842 13.6809 19.8555 14.9299 19.8555H18.1033C19.3523 19.8555 19.855 19.3842 19.855 18.2059L19.855 5.79502C19.855 4.61677 19.3523 4.14547 18.1033 4.14547L14.9299 4.14547C13.6809 4.14547 13.1782 4.61677 13.1782 5.79502Z" stroke="white" stroke-width="0.7855" stroke-linecap="round" stroke-linejoin="round" />
<path d="M4.14502 5.79502L4.14502 18.2059C4.14502 19.3842 4.64774 19.8555 5.89668 19.8555H9.07011C10.3191 19.8555 10.8218 19.3842 10.8218 18.2059L10.8218 5.79502C10.8218 4.61677 10.3191 4.14547 9.07011 4.14547L5.89668 4.14547C4.64774 4.14547 4.14502 4.61677 4.14502 5.79502Z" stroke="white" stroke-width="0.7855" stroke-linecap="round" stroke-linejoin="round" />
</svg>
);
};
export const FlexColumnIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.2055 13.1787H5.79457C4.61632 13.1787 4.14502 13.6814 4.14502 14.9304V18.1038C4.14502 19.3527 4.61632 19.8555 5.79457 19.8555H18.2055C19.3837 19.8555 19.855 19.3527 19.855 18.1038V14.9304C19.855 13.6814 19.3837 13.1787 18.2055 13.1787Z" stroke="white" stroke-width="0.7855" stroke-linecap="round" stroke-linejoin="round" />
<path d="M18.2055 4.14453H5.79457C4.61632 4.14453 4.14502 4.64725 4.14502 5.8962V9.06962C4.14502 10.3186 4.61632 10.8213 5.79457 10.8213H18.2055C19.3837 10.8213 19.855 10.3186 19.855 9.06962V5.8962C19.855 4.64725 19.3837 4.14453 18.2055 4.14453Z" stroke="white" stroke-width="0.7855" stroke-linecap="round" stroke-linejoin="round" />
</svg>
);
};
export const FlexRowReverseIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_6424_3252)">
<path d="M9.74963 5.82994L9.74963 18.241C9.74963 19.4193 10.2524 19.8906 11.5013 19.8906H14.6748C15.9238 19.8906 16.4265 19.4193 16.4265 18.241V5.82994C16.4265 4.65167 15.9238 4.18037 14.6748 4.18037H11.5013C10.2524 4.18037 9.74963 4.65167 9.74963 5.82994Z" stroke="white" stroke-linecap="round" stroke-linejoin="round" />
<path d="M0.716431 5.75865L0.716431 18.1698C0.716431 19.348 1.21916 19.8193 2.46812 19.8193H5.6416C6.89056 19.8193 7.39329 19.348 7.39329 18.1698L7.39329 5.75865C7.39329 4.58039 6.89056 4.10908 5.6416 4.10908H2.46812C1.21916 4.10908 0.716431 4.58039 0.716431 5.75865Z" stroke="white" stroke-linecap="round" stroke-linejoin="round" />
</g>
<g clip-path="url(#clip1_6424_3252)">
<path d="M20.1401 4.99716C21.33 7.07912 21.1304 8.85883 19.5408 10.3352C20.3157 8.55061 19.8845 6.96667 18.4644 5.7629L17.2075 6.3372L18.3451 3.28529L21.397 4.42286L20.1401 4.99716Z" fill="white" stroke="white" stroke-width="0.460612" stroke-linecap="round" stroke-linejoin="round" />
</g>
<defs>
<clipPath id="clip0_6424_3252">
<rect width="19.7634" height="20.6512" fill="white" transform="translate(0 3.34863)" />
</clipPath>
<clipPath id="clip1_6424_3252">
<rect width="9.37901" height="9.11321" fill="white" transform="matrix(0.400662 0.916226 -0.902414 0.43087 20.2422 0)" />
</clipPath>
</defs>
</svg>
);
};
export const FlexColumnReverseIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_6424_3258)">
<path d="M15.0643 13.1787H2.65C1.47143 13.1787 1 13.6816 1 14.9309V18.1051C1 19.3544 1.47143 19.8573 2.65 19.8573H15.0643C16.2429 19.8573 16.7143 19.3544 16.7143 18.1051V14.9309C16.7143 13.6816 16.2429 13.1787 15.0643 13.1787Z" stroke="white" stroke-linecap="round" stroke-linejoin="round" />
<path d="M15.0643 4.14355H2.65C1.47143 4.14355 1 4.64641 1 5.8957V9.06999C1 10.3193 1.47143 10.8221 2.65 10.8221H15.0643C16.2429 10.8221 16.7143 10.3193 16.7143 9.06999V5.8957C16.7143 4.64641 16.2429 4.14355 15.0643 4.14355Z" stroke="white" stroke-linecap="round" stroke-linejoin="round" />
</g>
<g clip-path="url(#clip1_6424_3258)">
<path d="M20.14 4.99716C21.3298 7.07912 21.1303 8.85883 19.5407 10.3352C20.3156 8.55061 19.8844 6.96667 18.4642 5.7629L17.2074 6.3372L18.345 3.28529L21.3969 4.42286L20.14 4.99716Z" fill="white" stroke="white" stroke-width="0.460612" stroke-linecap="round" stroke-linejoin="round" />
</g>
<defs>
<clipPath id="clip0_6424_3258">
<rect width="19.7634" height="20.6512" fill="white" transform="translate(0 3.34863)" />
</clipPath>
<clipPath id="clip1_6424_3258">
<rect width="9.37901" height="9.11321" fill="white" transform="matrix(0.400662 0.916226 -0.902414 0.43087 20.2422 0)" />
</clipPath>
</defs>
</svg>
);
};

View File

@@ -3,7 +3,7 @@ import { Line } from "react-chartjs-2";
import { Chart as ChartJS, LineElement, CategoryScale, LinearScale, PointElement } from "chart.js";
import { PowerIcon, ProductionCapacityIcon } from "../../icons/analysis";
import SkeletonUI from "../../templates/SkeletonUI";
import { useInputValues, useMachineUptime, useProductionCapacityData, useThroughPutData } from "../../../store/builder/store";
import { useInputValues, useMachineUptime, useProductionCapacityData } from "../../../store/builder/store";
ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);
@@ -28,7 +28,6 @@ const ThroughputSummary: React.FC = () => {
];
const { productionCapacityData } = useProductionCapacityData();
const { throughputData: data } = useThroughPutData();
const chartOptions = {
responsive: true,

View File

@@ -1,7 +1,6 @@
import React, { useEffect, useState } from "react";
import {
CostBreakDownIcon,
LightBulpIcon,
ROISummaryIcon,
ROISummaryProductName,
SonarCrownIcon,

View File

@@ -1,99 +1,111 @@
import { useEffect, useState } from "react";
import { useInputValues, useMachineCount, useMachineUptime, useMaterialCycle, useProductionCapacityData, useThroughPutData } from "../../../store/builder/store";
import {
ThroughputSummaryIcon,
} from "../../icons/analysis";
useInputValues,
useMachineUptime,
useMaterialCycle,
useThroughPutData,
} from "../../../store/builder/store";
import { ThroughputSummaryIcon } from "../../icons/analysis";
import SkeletonUI from "../../templates/SkeletonUI";
const ProductionCapacity = ({
avgProcessTime = "28.4 Secs/unit",
machineUtilization = "78%",
throughputValue = 128,
timeRange = { startTime: "08:00 AM", endTime: "09:00 AM" },
avgProcessTime = "28.4 Secs/unit",
machineUtilization = "78%",
throughputValue = 128,
timeRange = { startTime: "08:00 AM", endTime: "09:00 AM" },
}) => {
const { machineActiveTime } = useMachineUptime();
const { materialCycleTime } = useMaterialCycle();
const { throughputData } = useThroughPutData()
const { inputValues } = useInputValues();
const { machineActiveTime } = useMachineUptime();
const { materialCycleTime } = useMaterialCycle();
const { throughputData } = useThroughPutData();
const { inputValues } = useInputValues();
const progressPercent = machineActiveTime;
const progressPercent = machineActiveTime;
const shiftLength = parseFloat(inputValues["Shift length"]);
const shiftLength = parseFloat(inputValues["Shift length"]);
const totalBars = 6;
const barsToFill = Math.floor((progressPercent / 100) * totalBars);
const partialFillPercent = ((progressPercent / 1000) * totalBars - barsToFill) * 100;
const totalBars = 6;
const barsToFill = Math.floor((progressPercent / 100) * totalBars);
const partialFillPercent = ((progressPercent / 1000) * totalBars - barsToFill) * 100;
const [isLoading, setIsLoading] = useState(true);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
if (throughputData > 0) {
setIsLoading(false);
} else {
setIsLoading(false);
}
}, [throughputData])
useEffect(() => {
if (throughputData > 0) {
setIsLoading(false);
} else {
setIsLoading(false);
}
}, [throughputData]);
const Units_per_hour = ((shiftLength * 60) / (materialCycleTime / 60) / shiftLength)
const Units_per_hour = (shiftLength * 60) / (materialCycleTime / 60) / shiftLength;
return (
<>
{!isLoading && <div className="throughtputSummary-container analysis-card">
<div className="throughtputSummary-wrapper analysis-card-wrapper">
<div className="card-header">
<div className="header">
<div className="main-header">Throughput Summary</div>
<div className="sub-header">
{timeRange.startTime} - {timeRange.endTime}
</div>
</div>
<div className="icon-wrapper">
<ThroughputSummaryIcon />
</div>
</div>
{!isLoading ? (
<>
<div className="process-container">
<div className="throughput-value">
<span className="value">{(Units_per_hour).toFixed(2) === "Infinity"? 0 : (Units_per_hour).toFixed(2) }</span> Units/hour
</div>
return (
<>
{!isLoading && (
<div className="throughtputSummary-container analysis-card">
<div className="throughtputSummary-wrapper analysis-card-wrapper">
<div className="card-header">
<div className="header">
<div className="main-header">Throughput Summary</div>
<div className="sub-header">
{timeRange.startTime} - {timeRange.endTime}
</div>
</div>
<div className="icon-wrapper">
<ThroughputSummaryIcon />
</div>
</div>
{!isLoading ? (
<>
<div className="process-container">
<div className="throughput-value">
<span className="value">
{Units_per_hour.toFixed(2) === "Infinity"
? 0
: Units_per_hour.toFixed(2)}
</span>{" "}
Units/hour
</div>
{/* Dynamic Progress Bar */}
<div className="progress-bar-wrapper">
{[...Array(totalBars)].map((_, i) => (
<div className="progress-bar" key={i}>
{i < barsToFill ? (
<div className="bar-fill full" />
) : i === barsToFill ? (
<div
className="bar-fill partial"
style={{ width: `${partialFillPercent}%` }}
/>
) : null}
{/* Dynamic Progress Bar */}
<div className="progress-bar-wrapper">
{[...Array(totalBars)].map((_, i) => (
<div className="progress-bar" key={i}>
{i < barsToFill ? (
<div className="bar-fill full" />
) : i === barsToFill ? (
<div
className="bar-fill partial"
style={{ width: `${partialFillPercent}%` }}
/>
) : null}
</div>
))}
</div>
</div>
<div className="metrics-section">
<div className="metric">
<span className="label">Avg. Process Time</span>
<span className="value">
{materialCycleTime} secs/unit{" "}
</span>
</div>
<div className="metric">
<span className="label">Machine Utilization</span>
<span className="value">{machineActiveTime}</span>
{/* <span className="value">{machineActiveTime}</span> */}
</div>
</div>
</>
) : (
<SkeletonUI type={"default"} />
)}
</div>
))}
</div>
</div>
<div className="metrics-section">
<div className="metric">
<span className="label">Avg. Process Time</span>
<span className="value">{materialCycleTime} secs/unit </span>
</div>
<div className="metric">
<span className="label">Machine Utilization</span>
<span className="value">{machineActiveTime}</span>
{/* <span className="value">{machineActiveTime}</span> */}
</div>
</div>
</>
) : (
<SkeletonUI type={"default"} />
)}
</div>
</div>}
</>
);
)}
</>
);
};
export default ProductionCapacity;

View File

@@ -0,0 +1,128 @@
import React, { useState, useMemo, useRef, useEffect } from "react";
import { EyeDroperIcon, SearchIcon } from "../../icons/ExportCommonIcons";
export type DropdownItem = {
id: string;
label: string;
icon?: React.ReactNode;
};
type DataDetailedDropdownProps = {
title: string;
placeholder?: string;
sections: {
title?: string;
items: DropdownItem[];
}[];
value?: DropdownItem | null;
onChange?: (item: DropdownItem) => void;
dropDownHeader?: string;
eyedroper?: boolean;
};
const DataDetailedDropdown: React.FC<DataDetailedDropdownProps> = ({
title,
placeholder = "Select value",
sections,
value,
onChange,
dropDownHeader,
eyedroper,
}) => {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const [isEyeDroperActive, setIsEyeDroperActive] = useState(false)
const containerRef = useRef<HTMLDivElement>(null);
// Close dropdown on outside click
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
setOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
const filteredSections = useMemo(() => {
if (!search) return sections;
return sections
.map((section) => ({
...section,
items: section.items.filter((item) =>
item.label.toLowerCase().includes(search.toLowerCase())
),
}))
.filter((section) => section.items.length > 0);
}, [search, sections]);
return (
<div className="data-detailed-dropdown" ref={containerRef}>
<div className="title">{title}</div>
<div className="input-container">
<div className="input-wrapper">
<div className="input" onClick={() => setOpen((v) => !v)}>
{value?.label || placeholder}
<div className="icon"></div>
</div>
{open && (
<div className="dropdown-panel">
{dropDownHeader && <div className="heading">{dropDownHeader}</div>}
<div className="search">
<div className="icon">
<SearchIcon />
</div>
<input
placeholder="Search Assets"
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
</div>
{filteredSections.map((section, index) => (
<div key={index} className="data-section">
{section.title && (
<div className="data-header">
<div className="data-section-title">{section.title}</div>
<div className="data-section-count">{section.items.length}</div>
</div>
)}
{section.items.map((item) => (
<div
key={item.id}
className="item"
onClick={() => {
onChange?.(item);
setOpen(false);
}}
>
{item.icon && <span className="icon">{item.icon}</span>}
<span>{item.label}</span>
</div>
))}
</div>
))}
</div>
)}
</div>
{eyedroper && (
<div
className={`icon ${isEyeDroperActive ? "active" : ""}`}
onClick={() => setIsEyeDroperActive(!isEyeDroperActive)}
>
<EyeDroperIcon isActive={false} />
</div>
)}
</div>
</div>
);
};
export default DataDetailedDropdown;

View File

@@ -0,0 +1,55 @@
import React, { useState } from "react";
import RegularDropDown from "./RegularDropDown";
import { EyeDroperIcon } from "../../icons/ExportCommonIcons";
type DataSourceSelectorProps = {
label?: string;
options: string[];
selected?: string;
onSelect: (value: string) => void;
eyeDropperActive?: boolean; // initial state
showEyeDropper?: boolean;
};
const DataSourceSelector: React.FC<DataSourceSelectorProps> = ({
label = "Data Source",
options,
selected,
onSelect,
showEyeDropper = true,
}) => {
// Local state to toggle EyeDropper
const [isEyeActive, setIsEyeActive] = useState(false);
return (
<div className="datas">
<div className="datas__label">{label}</div>
<div className="datas__class">
<RegularDropDown
header={selected || "Select value"}
options={options}
onSelect={onSelect}
search={false}
/>
{showEyeDropper && (
<div
className={`icon ${isEyeActive ? "active" : ""}`}
onClick={() => setIsEyeActive(!isEyeActive)}
style={{ cursor: "pointer" }}
>
{/* Pass the local state here */}
<EyeDroperIcon isActive={isEyeActive} />
</div>
)}
</div>
</div>
);
};
export default DataSourceSelector;

View File

@@ -88,3 +88,7 @@ const InputWithDropDown: React.FC<InputWithDropDownProps> = ({
};
export default InputWithDropDown;

View File

@@ -1,10 +1,5 @@
import React, { useState, useRef, useEffect } from "react";
// interface RenameInputProps {
// value: string;
// onRename?: (newText: string) => void;
// }
interface RenameInputProps {
value: string;
onRename?: (newText: string) => void;

View File

@@ -12,7 +12,7 @@
left: 0;
pointer-events: none;
* > {
*> {
pointer-events: auto;
}
@@ -272,11 +272,22 @@
box-shadow: 0px 4px 8px rgba(60, 60, 67, 0.1019607843);
z-index: 3;
display: flex;
flex-direction: column;
gap: 11px;
min-width: 280px;
height: fit-content;
min-width: 320px;
min-height: 60vh;
padding: 12px;
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 0 10px 0;
// margin: 0 0 10px 0;
border-bottom: 1px solid gray;
padding-bottom: 10px;
@@ -296,6 +307,223 @@
}
}
.icon {
display: flex;
}
.design-section {
padding: 4px;
outline: 1px solid var(--border-color);
outline-offset: -1px;
border-radius: 12px;
background: var(--background-color);
padding: 14px 12px;
display: flex;
flex-direction: column;
gap: 11px;
.value-field-container {
padding: 0;
margin: 0;
// padding: 6px 0px;
}
.select-type {
display: flex;
.type {
flex: 1;
padding: 4px 0;
text-align: center;
border-radius: 100px;
&.active {
background-color: var(--background-color-button);
}
}
}
.position-canvas {
background: #8D70AD33;
height: 110px;
border-radius: 17px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
.canvas {
width: 60%;
height: 27px;
background: #E0DFFF80;
// position: relative;
.value {
position: absolute;
input {
// border: none;
// outline: none;
width: 20px;
background: transparent;
}
&:nth-child(1) {
top: 20px;
left: 50%;
transform: translateX(-50%);
}
&:nth-child(2) {
top: 50%;
right: 35px;
transform: translateY(-50%);
}
&:nth-child(3) {
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
&:nth-child(4) {
top: 50%;
left: 35px;
transform: translateY(-50%);
}
}
}
}
.alignments-section {
display: flex;
justify-content: center;
gap: 7px;
.section {
border-radius: 100px;
padding: 6px;
display: flex;
gap: 10px;
width: fit-content;
}
.icon {
&.active {
background-color: var(--background-color-button);
border-radius: 2px;
}
}
}
.input-range-container {
margin: 0;
padding: 0;
}
.data-picker {
display: flex;
justify-content: space-between;
align-items: center;
.label {
width: 50%;
white-space: nowrap;
}
input[type="color"] {
width: 42px;
padding: 0;
background: transparent;
outline: none;
}
.left {
width: 100%;
display: flex;
align-items: center;
gap: 6px;
.colorValue {
width: 100%;
background: linear-gradient(90.85deg, rgba(240, 228, 255, 0.3) 3.6%, rgba(211, 174, 253, 0.3) 96.04%);
text-align: center;
padding: 4px 0;
border-radius: 100px;
}
}
}
.design-section-footer {
display: flex;
gap: 7px;
label,
.input {
width: auto;
}
input {
width: 40px;
}
.input-range-container,
.value-field-container {
width: 100%;
display: flex;
gap: 6px;
.input-container {
width: 100%;
display: flex;
gap: 6px;
input[type="range"] {
margin: 0;
width: 70px;
}
}
}
}
}
.datas {
// width: 100% ;
display: flex;
justify-content: space-between;
align-items: center;
.datas__label,
.datas__class {
flex: 1;
}
}
.type-switch {
display: flex;
padding: 6px 12px;
.type {
flex: 1;
text-align: center;
padding: 4px 0;
border-radius: 19px;
cursor: pointer;
&.active {
background: var(--background-color-button);
}
}
}
&.data-model-panel {
left: 20px;
top: 50px;
@@ -311,21 +539,171 @@
}
}
&.block-editor-panel {
min-width: 280px;
height: fit-content;
&.block-editor-panel {
// h4 {
// color: #4caf50;
// }
.design-section-wrapper {
display: flex;
flex-direction: column;
gap: 6px;
}
}
.data-details {
display: flex;
flex-direction: column;
gap: 6px;
.data-wrapper {
display: flex;
flex-direction: column;
gap: 6px;
padding: 6px 12px;
.value-field-container {
margin: 0;
padding: 0;
.label,
.input.default {
width: auto;
flex: 1;
}
input,
.input-wrapper {
background: transparent;
}
}
.data {
display: flex;
justify-content: center;
align-items: center;
gap: 9px;
.datas_label,
.regularDropdown-container {
flex: 1;
}
}
}
.data-mapping {
display: flex;
flex-direction: column;
gap: 9px;
background: var(--background-color);
border: 1px solid var(--border-color);
box-shadow: var(--box-shadow-medium);
padding: 15px 12px;
border-radius: 25px;
.heading {
text-align: center;
}
.type-switch {}
.fields-wrapper {
display: flex;
flex-direction: column;
gap: 6px;
.datas {
width: 100%;
display: flex;
align-items: center;
// padding: 6px 12px;
.datas__label,
.datas__class {
flex: 1;
}
.datas__label {
flex: 0.8;
}
.datas__class {
display: flex;
align-items: center;
gap: 4px;
.icon {
display: flex;
padding: 3px;
border-radius: 2px;
&.active {
background: var(--background-color-button);
}
}
.regularDropdown-container {
.icon {
padding: 0;
}
}
}
}
.add-field {
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
svg path {
stroke: #CCACFF !important;
}
.label {
color: #CCACFF;
}
}
}
}
}
&.element-editor-panel {
right: 20px;
top: 50px;
min-width: 300px;
// min-width: 300px;
max-height: 84vh;
overflow: auto;
max-width: 320px;
.appearance {
.design-datas-wrapper {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px 16px;
.value-field-container {
label {
width: 80%;
text-wrap: nowrap;
}
}
}
}
.footer {
text-align: center;
color: #CCACFF;
}
}
}
@@ -534,3 +912,143 @@
}
}
}
// DataDetailedDropdown
.data-detailed-dropdown {
display: flex;
width: 100%;
.title,
.input-container {
flex: 1;
}
.input-container {
width: 100%;
display: flex;
align-items: center;
gap: 6px;
.input-wrapper {
width: 100%;
background: transparent;
}
.icon {
display: flex;
padding: 2px;
border-radius: 2px;
&.active {
background: var(--background-color-button);
}
cursor: pointer;
}
}
.input-wrapper {
outline: 1px solid var(--input-border-color);
outline-offset: -1px;
border: none;
background: var(--background-color-input);
color: var(--input-text-color);
border-radius: 100px;
position: relative;
.input {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 8px;
}
.dropdown-panel {
position: absolute;
z-index: 1;
top: 0;
right: 0;
transform: translateY(30px);
min-width: 200px;
padding: 12px;
outline: 1px solid var(--border-color);
outline-offset: -1px;
border-radius: 12px;
background: var(--background-color);
backdrop-filter: blur(20px);
display: flex;
flex-direction: column;
gap: 8px;
.search {
outline: 1px solid var(--border-color);
outline-offset: -1px;
border-radius: 12px;
background: var(--background-color);
display: flex;
align-items: center;
padding: 4px 9px;
.icon {
height: 10px;
display: flex;
justify-content: center;
align-items: center;
}
input {
outline: none;
border: none;
background: transparent;
padding: 0;
padding-left: 3px;
}
}
.data-section {
.data-header {
display: flex;
justify-content: space-between;
align-items: center;
.data-section-count {
font-size: 10px;
}
}
.item {
padding: 8px 0;
display: flex;
gap: 2px;
align-items: center;
.icon {
display: flex;
justify-content: center;
align-items: center;
}
&.active {
span {
color: #CCACFF;
}
}
}
}
}
}
}