git templates updated

This commit is contained in:
Vishnu 2025-03-19 09:13:23 +05:30
parent cdf8dbbdba
commit 124e435504
39 changed files with 1650 additions and 73 deletions

View File

@ -0,0 +1,40 @@
---
name: Bug Report
about: Report a bug or issue with the project
title: "[Bug] "
labels: bug
assignees: ''
---
### Bug Description
Provide a detailed description of the bug or issue.
### Steps to Reproduce
1. Step one
2. Step two
3. Step three
### Expected Behavior
Explain what you expected to happen.
### Actual Behavior
Describe what actually happened, including any error messages or logs.
### Screenshots (if applicable)
If applicable, add screenshots to help explain your problem.
### Environment Information:
- Operating System: [e.g., macOS, Windows, Linux]
- Browser (if applicable): [e.g., Chrome, Firefox]
- Version: [e.g., 1.0.0]

View File

@ -0,0 +1,22 @@
---
name: Feature Request
about: Suggest a new feature for the project
title: "[Feature Request] "
labels: enhancement
assignees: ''
---
### Feature Request Description
Provide a clear and concise description of the feature youd like to request.
### Why Is This Feature Needed?
Explain why the feature would be useful or necessary.
### Additional Context
Add any other context or screenshots that may help describe the feature request.

View File

@ -0,0 +1,24 @@
### Description
Please include a summary of the changes and the motivation behind them. Also include any relevant context or links to related issues.
**Related Issues:**
- Issue # (if applicable)
- Link to related issue or ticket (if applicable)
### Changes Made
- Describe what changes were made in this pull request.
- Include any relevant details about the implementation.
### Checklist
- [ ] I have tested my changes locally.
- [ ] I have updated the documentation (if applicable).
- [ ] I have included unit tests (if applicable).
- [ ] My code follows the project's coding style.
### Screenshots (if applicable)
![screenshot](link_to_screenshot)

View File

@ -0,0 +1,24 @@
---
name: Documentation Update
about: Submit a pull request for updating documentation
title: "[Docs] "
labels: documentation, needs review
assignees: ''
---
### Documentation Changes
Please describe the changes you are making to the documentation.
### Related Code Changes (if applicable)
If your documentation relates to any new code changes, please provide context or links to those changes.
### Reason for Change
Why are these documentation updates necessary?
### Screenshots (if applicable)
If updating visual elements of documentation, provide screenshots or examples.

View File

@ -0,0 +1,28 @@
---
name: Feature Request
about: Submit a pull request for adding a new feature
title: "[Feature] "
labels: enhancement, needs review
assignees: ''
---
### Description of the Feature
Briefly describe the new feature you are implementing.
**Related Issue:** (if any)
### Changes Made
1. context-menu-list the specific changes made in the code.
2. Explain the new functionality and how it improves the project.
### Testing and Documentation
1. Steps for testing the new feature.
2. Any documentation updates made.
### Screenshots (if applicable)
Add any screenshots or visuals demonstrating the feature.

24
app/.github/workflows/deploy-docs.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: Deploy Docsify
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: npm install
- name: Build Docsify site
run: docsify serve docs --port 4000

View File

@ -90,7 +90,7 @@ export function FlipZAxisIcon() {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_111_550)">
<g clipPath="url(#clip0_111_550)">
<path
d="M9.04893 11.25H2.95106C2.10217 11.25 1.67773 11.25 1.53852 11.0466C1.39931 10.8432 1.64602 10.5835 2.13942 10.0641L2.7027 9.47111C2.92208 9.24016 3.03177 9.12469 3.19288 9.06234C3.35399 9 3.54271 9 3.92015 9H8.07988C8.4573 9 8.64602 9 8.80715 9.06234C8.96823 9.12469 9.07795 9.24016 9.29734 9.4711L9.86058 10.0641C10.354 10.5835 10.6007 10.8432 10.4615 11.0466C10.3223 11.25 9.89784 11.25 9.04893 11.25Z"
fill="var(--text-color)"

View File

@ -97,7 +97,7 @@ export function EyeIcon({ isClosed }: { isClosed: boolean }) {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_889_1582)">
<g clipPath="url(#clip0_889_1582)">
<path
d="M1.52462 4.65539C1.50864 4.60647 1.5 4.55424 1.5 4.5C1.5 4.22386 1.72386 4 2 4C2.22985 4 2.42348 4.1551 2.48194 4.36634C3.52484 7.8593 8.4728 7.8601 9.5174 4.36868C9.5751 4.15624 9.7693 4 10 4C10.2761 4 10.5 4.22386 10.5 4.5C10.5 4.5534 10.4916 4.60485 10.4761 4.6531C10.2758 5.3241 9.96205 5.8938 9.56935 6.3622L10.2072 7C10.4024 7.19525 10.4024 7.51185 10.2072 7.7071C10.0119 7.90235 9.6953 7.90235 9.50005 7.7071L8.84435 7.0514C8.48725 7.3213 8.0956 7.53275 7.6843 7.6858L7.8632 8.35355C7.9347 8.6203 7.7764 8.89445 7.50965 8.9659C7.2429 9.0374 6.96875 8.8791 6.8973 8.61235L6.71555 7.9341C6.2418 8.0042 5.7582 8.0042 5.28445 7.9341L5.1027 8.61235C5.03125 8.8791 4.75708 9.0374 4.49035 8.9659C4.22361 8.89445 4.06533 8.6203 4.1368 8.35355L4.31572 7.6858C3.90446 7.53275 3.5128 7.3213 3.15573 7.05145L2.50009 7.7071C2.30482 7.90235 1.98824 7.90235 1.79298 7.7071C1.59771 7.51185 1.59771 7.19525 1.79298 7L2.43074 6.36225C2.03845 5.89435 1.72505 5.3254 1.52462 4.65539Z"
fill="var(--text-color)"
@ -214,7 +214,7 @@ export function SettingsIcon() {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_111_481)">
<g clipPath="url(#clip0_111_481)">
<path
d="M6 7.5C6.82843 7.5 7.5 6.82843 7.5 6C7.5 5.17157 6.82843 4.5 6 4.5C5.17157 4.5 4.5 5.17157 4.5 6C4.5 6.82843 5.17157 7.5 6 7.5Z"
stroke="var(--text-color)"
@ -242,7 +242,7 @@ export function HelpIcon() {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_111_484)">
<g clipPath="url(#clip0_111_484)">
<path
d="M6 12C2.6862 12 0 9.3138 0 6C0 2.6862 2.6862 0 6 0C9.3138 0 12 2.6862 12 6C12 9.3138 9.3138 12 6 12ZM3.552 4.3404V4.4016C3.552 4.48117 3.58361 4.55747 3.63987 4.61373C3.69613 4.66999 3.77244 4.7016 3.852 4.7016H4.4502C4.48952 4.7016 4.52845 4.69386 4.56478 4.67881C4.6011 4.66376 4.63411 4.64171 4.66191 4.61391C4.68971 4.58611 4.71176 4.5531 4.72681 4.51678C4.74186 4.48045 4.7496 4.44152 4.7496 4.4022C4.7496 3.6282 5.3484 3.2148 6.1536 3.2148C6.9384 3.2148 7.4544 3.6282 7.4544 4.2168C7.4544 4.7736 7.1652 5.0322 6.4428 5.3628L6.2364 5.4552C5.6274 5.724 5.4 6.126 5.4 6.8286V6.9C5.4 6.97957 5.43161 7.05587 5.48787 7.11213C5.54413 7.16839 5.62044 7.2 5.7 7.2H6.2982C6.33752 7.2 6.37645 7.19226 6.41278 7.17721C6.4491 7.16216 6.48211 7.14011 6.50991 7.11231C6.53771 7.08451 6.55976 7.0515 6.57481 7.01518C6.58986 6.97885 6.5976 6.93992 6.5976 6.9006C6.5976 6.591 6.6804 6.4668 6.9276 6.3534L7.1346 6.2604C8.0016 5.868 8.652 5.352 8.652 4.2264V4.1646C8.652 2.9778 7.62 2.1 6.1536 2.1C4.6668 2.1 3.552 2.9568 3.552 4.3404ZM5.1 8.9946C5.1 9.5148 5.4954 9.9 5.9946 9.9C6.5046 9.9 6.9 9.5148 6.9 8.9946C6.9 8.4744 6.5046 8.1 5.9946 8.1C5.4954 8.1 5.1 8.4744 5.1 8.9946Z"
fill="var(--text-color)"
@ -266,7 +266,7 @@ export function TrashIcon() {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_111_486)">
<g clipPath="url(#clip0_111_486)">
<path
d="M4.70587 5.32353V9.02941M7.17646 5.32353V9.02941M9.64704 2.85294V10.2647C9.64704 10.947 9.094 11.5 8.41175 11.5H3.47057C2.78834 11.5 2.23528 10.947 2.23528 10.2647V2.85294M0.999985 2.85294H10.8823M7.7941 2.85294V2.23529C7.7941 1.55306 7.24106 1 6.55881 1H5.32351C4.64128 1 4.08822 1.55306 4.08822 2.23529V2.85294"
stroke="var(--text-color)"
@ -292,7 +292,11 @@ export function FilterIcon() {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M6.86655 10V3.33333" stroke="var(--text-color)" strokeLinecap="round" />
<path
d="M6.86655 10V3.33333"
stroke="var(--text-color)"
strokeLinecap="round"
/>
<path
d="M6.86655 16.6666V13.3333"
stroke="var(--text-color)"
@ -401,3 +405,62 @@ export function RedoIcon() {
</svg>
);
}
export function ResizeHeightIcon() {
return (
<svg
width="15"
height="7"
viewBox="0 0 15 7"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="1.5" cy="1.63281" r="1.5" fill="var(--text-disabled)" />
<circle cx="5.3667" cy="1.63281" r="1.5" fill="var(--text-disabled)" />
<circle cx="9.2334" cy="1.63281" r="1.5" fill="var(--text-disabled)" />
<circle cx="13.1001" cy="1.63281" r="1.5" fill="var(--text-disabled)" />
<circle cx="1.5" cy="5.5" r="1.5" fill="var(--text-disabled)" />
<circle cx="5.3667" cy="5.5" r="1.5" fill="var(--text-disabled)" />
<circle cx="9.2334" cy="5.5" r="1.5" fill="var(--text-disabled)" />
<circle cx="13.1001" cy="5.5" r="1.5" fill="var(--text-disabled)" />
</svg>
);
}
export function RemoveIcon() {
return (
<svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M3 6.5H9" stroke="var(--text-color)" stroke-linecap="round" />
</svg>
);
}
export function InfoIcon() {
return (
<svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.46289 7.75441C5.46289 7.68342 5.47691 7.6131 5.50422 7.54758C5.53158 7.48201 5.57156 7.42254 5.62201 7.37257C5.67246 7.3226 5.73231 7.2831 5.79807 7.25636C5.86388 7.22963 5.93425 7.21619 6.00529 7.21681C6.11003 7.21873 6.21188 7.25142 6.29814 7.31089C6.38435 7.37036 6.45121 7.45398 6.49019 7.55118C6.52921 7.64843 6.53862 7.75499 6.5174 7.85757C6.49614 7.96014 6.44511 8.05417 6.37071 8.12795C6.29631 8.20168 6.20185 8.25184 6.09908 8.27219C5.99631 8.29254 5.8898 8.28212 5.79294 8.24224C5.69603 8.2024 5.61308 8.13486 5.55438 8.04808C5.49567 7.96134 5.46385 7.8592 5.46289 7.75441ZM5.63564 6.44401L5.56844 3.93842C5.56206 3.87819 5.56844 3.81729 5.58716 3.75968C5.60583 3.70207 5.63641 3.64902 5.67692 3.604C5.71743 3.55897 5.76697 3.52297 5.82227 3.49832C5.87761 3.47368 5.93751 3.46094 5.99804 3.46094C6.05862 3.46094 6.11852 3.47368 6.17387 3.49832C6.22916 3.52297 6.2787 3.55897 6.31921 3.604C6.35972 3.64902 6.3903 3.70207 6.40897 3.75968C6.42769 3.81729 6.43407 3.87819 6.42769 3.93842L6.36529 6.44401C6.36529 6.54073 6.32689 6.63356 6.25844 6.70196C6.19004 6.77036 6.09721 6.80881 6.00049 6.80881C5.90372 6.80881 5.81094 6.77036 5.74254 6.70196C5.67414 6.63356 5.63564 6.54073 5.63564 6.44401Z"
fill="var(--text-color)"
/>
<path
d="M6.00006 10.3175C8.45219 10.3175 10.4401 8.32963 10.4401 5.8775C10.4401 3.42536 8.45219 1.4375 6.00006 1.4375C3.54792 1.4375 1.56006 3.42536 1.56006 5.8775C1.56006 8.32963 3.54792 10.3175 6.00006 10.3175Z"
stroke="var(--text-color)"
stroke-width="0.72"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
);
}

View File

@ -7,7 +7,7 @@ export function ZoneIcon({ isActive }: { isActive: boolean }) {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_111_378)">
<g clipPath="url(#clip0_111_378)">
<path
d="M1.66665 16.6667H2.49998V17.5H0.833313V15.8333H1.66665V16.6667ZM18.3333 16.6667H17.5V17.5H19.1666V15.8333H18.3333V16.6667ZM0.833313 4.16667H1.66665V3.33333H2.49998V2.5H0.833313V4.16667ZM1.66665 5.83333H0.833313V7.5H1.66665V5.83333ZM1.66665 9.16667H0.833313V10.8333H1.66665V9.16667ZM18.3333 7.5H19.1666V5.83333H18.3333V7.5ZM18.3333 10.8333H19.1666V9.16667H18.3333V10.8333ZM1.66665 12.5H0.833313V14.1667H1.66665V12.5ZM18.3333 14.1667H19.1666V12.5H18.3333V14.1667ZM4.16665 3.33333H5.83331V2.5H4.16665V3.33333ZM9.16665 3.33333V2.5H7.49998V3.33333H9.16665ZM10.8333 3.33333H12.5V2.5H10.8333V3.33333ZM15.8333 2.5H14.1666V3.33333H15.8333V2.5ZM4.16665 17.5H5.83331V16.6667H4.16665V17.5ZM7.49998 17.5H9.16665V16.6667H7.49998V17.5ZM10.8333 17.5H12.5V16.6667H10.8333V17.5ZM14.1666 17.5H15.8333V16.6667H14.1666V17.5ZM17.5 3.33333H18.3333V4.16667H19.1666V2.5H17.5V3.33333ZM10.4166 6.66667V8.33333C10.4164 8.55428 10.3286 8.76611 10.1723 8.92235C10.0161 9.07858 9.80426 9.16645 9.58331 9.16667H4.16665C3.9457 9.16645 3.73387 9.07858 3.57763 8.92235C3.4214 8.76611 3.33353 8.55428 3.33331 8.33333V6.66667C3.33353 6.44572 3.4214 6.23389 3.57763 6.07765C3.73387 5.92142 3.9457 5.83355 4.16665 5.83333H9.58331C9.80426 5.83355 10.0161 5.92142 10.1723 6.07765C10.3286 6.23389 10.4164 6.44572 10.4166 6.66667ZM9.58415 8.33333L9.58331 6.66667H4.16665V8.33333H9.58415ZM16.6666 11.6667V13.3333C16.6664 13.5543 16.5786 13.7661 16.4223 13.9223C16.2661 14.0786 16.0543 14.1664 15.8333 14.1667H11.25C11.029 14.1664 10.8172 14.0786 10.661 13.9223C10.5047 13.7661 10.4169 13.5543 10.4166 13.3333V11.6667C10.4169 11.4457 10.5047 11.2339 10.661 11.0777C10.8172 10.9214 11.029 10.8336 11.25 10.8333H15.8333C16.0543 10.8336 16.2661 10.9214 16.4223 11.0777C16.5786 11.2339 16.6664 11.4457 16.6666 11.6667ZM15.8341 13.3333L15.8333 11.6667H11.25V13.3333H15.8341Z"
fill={isActive ? "var(--primary-color)" : "var(--text-color)"}
@ -125,7 +125,7 @@ export function WallIcon({ isActive }: { isActive: boolean }) {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_204_497)">
<g clipPath="url(#clip0_204_497)">
<path
d="M12.6101 7.17339H6.72171V10.7064H12.6101V7.17339Z"
fill="var(--highlight-accent-color)"
@ -203,7 +203,7 @@ export function WallIcon({ isActive }: { isActive: boolean }) {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_111_392)">
<g clipPath="url(#clip0_111_392)">
<path
d="M12.6101 7.17339H6.72173V10.7064H12.6101V7.17339Z"
stroke="var(--text-color)"

View File

@ -40,8 +40,40 @@ export function ToggleSidebarIcon() {
height="13.0909"
fill="var(--accent-color)"
/>
<circle cx="6.27271" cy="8.72834" r="0.818182" fill="var(--accent-color)" />
<circle cx="6.27271" cy="11.1815" r="0.818182" fill="var(--accent-color)" />
<circle
cx="6.27271"
cy="8.72834"
r="0.818182"
fill="var(--accent-color)"
/>
<circle
cx="6.27271"
cy="11.1815"
r="0.818182"
fill="var(--accent-color)"
/>
</svg>
);
}
export function AppDockIcon() {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<ellipse cx="3" cy="3" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="10" cy="3" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="17" cy="3" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="3" cy="10" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="10" cy="10" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="17" cy="10" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="3" cy="17" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="10" cy="17" rx="2" ry="2" fill="var(--text-color)" />
<ellipse cx="17" cy="17" rx="2" ry="2" fill="var(--text-color)" />
</svg>
);
}

View File

@ -0,0 +1,70 @@
export function AnalysisIcon({ isActive }: { isActive: boolean }) {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.5002 12.4987L15.1418 10.1404M10.8335 14.1654H5.8335M7.50016 10.832H5.8335M10.8335 8.33203C10.8335 8.82648 10.9801 9.30983 11.2548 9.72096C11.5295 10.1321 11.92 10.4525 12.3768 10.6417C12.8336 10.8309 13.3363 10.8805 13.8212 10.784C14.3062 10.6875 14.7516 10.4494 15.1013 10.0998C15.4509 9.75017 15.689 9.30471 15.7855 8.81976C15.8819 8.3348 15.8324 7.83214 15.6432 7.37532C15.454 6.91851 15.1335 6.52806 14.7224 6.25336C14.3113 5.97865 13.8279 5.83203 13.3335 5.83203C12.6705 5.83203 12.0346 6.09542 11.5657 6.56426C11.0969 7.03311 10.8335 7.66899 10.8335 8.33203Z"
stroke={isActive ? "var(--primary-color)" : "var(--text-color)"}
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M14.1667 14.1667V16.6667C14.1667 16.8877 14.0789 17.0996 13.9226 17.2559C13.7663 17.4122 13.5543 17.5 13.3333 17.5H3.33333C3.11232 17.5 2.90036 17.4122 2.74408 17.2559C2.5878 17.0996 2.5 16.8877 2.5 16.6667V3.33333C2.5 3.11232 2.5878 2.90036 2.74408 2.74408C2.90036 2.5878 3.11232 2.5 3.33333 2.5H13.3333"
stroke={isActive ? "var(--primary-color)" : "var(--text-color)"}
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
);
}
export function MechanicsIcon({ isActive }: { isActive: boolean }) {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.69 11.7629L16.4912 11.5885C16.4161 11.5828 16.3514 11.5356 16.3226 11.466L15.9339 10.5281C15.9049 10.4588 15.917 10.3794 15.9662 10.3224L16.6834 9.35896C16.7973 9.22544 16.7898 9.02639 16.6655 8.90212L16.098 8.3348C15.974 8.21053 15.7746 8.20247 15.6414 8.31697L14.6776 9.03387C14.621 9.08282 14.541 9.09546 14.4719 9.0667L13.5338 8.67776C13.4644 8.64929 13.417 8.58341 13.4109 8.50918L13.2372 7.31068C13.2234 7.1352 13.0772 7 12.9018 7H12.0991C11.9234 7 11.7772 7.1352 11.7637 7.31068L11.5893 8.50918C11.5839 8.58399 11.5364 8.64929 11.4671 8.67776L10.5286 9.0667C10.4593 9.09546 10.3799 9.08282 10.3227 9.03387L9.35945 8.31697C9.22628 8.20276 9.0272 8.2105 8.90264 8.3348L8.33532 8.90212C8.21105 9.02639 8.20357 9.22547 8.31746 9.35896L9.03439 10.3227C9.08302 10.3794 9.09598 10.4591 9.06693 10.5281L8.67825 11.466C8.65007 11.5356 8.58448 11.5828 8.50996 11.5889L7.31062 11.7629C7.13569 11.7767 7.00049 11.9229 7.00049 12.0986V12.901C7.00049 13.0765 7.13572 13.2232 7.31062 13.2364L8.50996 13.4105C8.58448 13.4165 8.65007 13.464 8.67825 13.5333L9.06693 14.4712C9.09598 14.5408 9.08305 14.6205 9.03439 14.6772L8.31746 15.641C8.20354 15.7744 8.21102 15.9729 8.33532 16.0978L8.90264 16.6651C9.0272 16.7894 9.22628 16.7969 9.35945 16.6827L10.3227 15.9654C10.3799 15.9171 10.4593 15.9042 10.5286 15.9333L11.4671 16.3216C11.5364 16.3507 11.5839 16.4157 11.5897 16.4908L11.7637 17.6893C11.7775 17.8645 11.9234 18 12.0991 18H12.9018C13.0776 18 13.2234 17.8645 13.2372 17.6893L13.411 16.4908C13.417 16.4157 13.4645 16.3507 13.5338 16.3216L14.4722 15.9333C14.5413 15.9042 14.6213 15.9171 14.6779 15.9654L15.6414 16.6827C15.7746 16.7969 15.974 16.7894 16.098 16.6651L16.6656 16.0978C16.7902 15.9729 16.7974 15.7744 16.6834 15.641L15.9662 14.6772C15.9179 14.6205 15.9049 14.5408 15.934 14.4712L16.3226 13.5333C16.3514 13.464 16.4161 13.4165 16.4912 13.4105L17.69 13.2364C17.8652 13.2232 18.0004 13.0765 18.0004 12.901V12.0986C18.0004 11.9228 17.8652 11.7767 17.69 11.7629ZM13.8191 13.8187C13.4667 14.1706 12.9987 14.3645 12.5004 14.3645C12.0024 14.3645 11.5337 14.1706 11.1816 13.8187C10.8295 13.466 10.6353 12.9979 10.6353 12.4997C10.6353 12.0017 10.8295 11.5333 11.1816 11.1812C11.5337 10.8285 12.0024 10.6351 12.5004 10.6351C12.9987 10.6351 13.4667 10.8285 13.8191 11.1812C14.1712 11.5333 14.3652 12.0017 14.3652 12.4997C14.3652 12.9979 14.1713 13.466 13.8191 13.8187Z"
stroke={isActive ? "var(--primary-color)" : "var(--text-color)"}
/>
<path
d="M6.7961 8.78085C6.92052 8.73626 6.98909 8.60354 6.95416 8.47635L6.77216 7.58599C6.75759 7.53147 6.77438 7.47339 6.81595 7.43541L7.37949 6.92253C7.42078 6.88482 7.48083 6.87353 7.53285 6.89334L8.39565 7.15458C8.51874 7.20111 8.65747 7.1455 8.71367 7.02603L8.96969 6.48121C9.02637 6.36145 8.98098 6.21939 8.86644 6.1544L8.11541 5.65637C8.06665 5.62829 8.03718 5.57515 8.04024 5.51899L8.07603 4.75805C8.07906 4.70161 8.11263 4.65178 8.1636 4.62864L8.96614 4.20052C9.08642 4.14683 9.14452 4.00865 9.09994 3.88532L8.89619 3.31844C8.85132 3.19427 8.7186 3.12546 8.59144 3.16042L7.70081 3.34183C7.64628 3.35726 7.58873 3.34019 7.5505 3.29832L7.03784 2.73511C6.99958 2.69324 6.98804 2.63436 7.00837 2.58151L7.26967 1.71923C7.31617 1.59562 7.2606 1.45713 7.14084 1.40122L6.59627 1.14492C6.47679 1.08873 6.33417 1.13362 6.26894 1.24841L5.77118 1.99948C5.74335 2.04823 5.69024 2.07764 5.63405 2.07492L4.87311 2.03885C4.81695 2.03638 4.76629 2.00167 4.74345 1.951L4.31589 1.14877C4.26165 1.02849 4.12399 0.970357 4.0001 1.01498L3.43353 1.21897C3.30936 1.26359 3.24055 1.39603 3.27579 1.52319L3.45748 2.4141C3.47235 2.46804 3.45556 2.52642 3.41372 2.56413L2.85014 3.07729C2.8083 3.115 2.74912 3.12657 2.69626 3.10676L1.83398 2.84521C1.71093 2.79843 1.57244 2.85459 1.516 2.97404L1.25995 3.51864C1.20379 3.63812 1.24865 3.78074 1.3632 3.84569L2.11423 4.34373C2.16323 4.37156 2.19242 4.42442 2.1894 4.48058L2.1536 5.24152C2.15141 5.29824 2.11698 5.34779 2.06606 5.37091L1.26353 5.79899C1.14318 5.85296 1.08511 5.99089 1.12973 6.11423L1.33373 6.68107C1.37832 6.80524 1.51103 6.87405 1.63795 6.8394L2.52914 6.65716C2.58311 6.64228 2.64146 6.65935 2.67916 6.70119L3.19176 7.26449C3.23003 7.30633 3.24107 7.36579 3.2212 7.41838L2.95996 8.28065C2.91371 8.40399 2.96935 8.54247 3.08879 8.59863L3.63336 8.85466C3.75312 8.91109 3.89543 8.86567 3.9607 8.75141L4.45818 8.0001C4.48626 7.95165 4.53911 7.9219 4.59555 7.92517L5.35652 7.96097C5.41296 7.96375 5.46307 7.99732 5.48646 8.04879L5.91374 8.85074C5.96827 8.97108 6.10564 9.02971 6.2295 8.98509L6.7961 8.78085ZM5.58891 6.31659C5.23732 6.44295 4.85716 6.42533 4.51878 6.2662C4.18043 6.10707 3.92493 5.82571 3.79802 5.47385C3.67166 5.12201 3.68928 4.7421 3.84844 4.40403C4.00754 4.0654 4.28917 3.8099 4.64076 3.68329C4.99259 3.55662 5.37251 3.57424 5.71058 3.73393C6.04865 3.89251 6.3047 4.17389 6.43159 4.52573C6.55798 4.87759 6.54008 5.25723 6.38123 5.59561C6.22154 5.93365 5.94043 6.18967 5.58891 6.31659Z"
stroke={isActive ? "var(--primary-color)" : "var(--text-color)"}
/>
</svg>
);
}
export function PropertiesIcon({ isActive }: { isActive: boolean }) {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.4254 15.3839L8.67142 6.79353C8.79789 6.57037 8.90139 6.337 8.97464 6.09625C8.98245 6.01909 8.99808 5.93903 9.02639 5.85746C9.04151 5.81156 9.05423 5.76468 9.06692 5.71831C9.26711 4.6353 8.94923 3.4756 8.11182 2.63819C7.84716 2.37353 7.54982 2.16113 7.23341 2C7.21778 2 7.20216 2.00197 7.18703 2.00538L6.90578 2.07422C6.85303 2.08791 6.80762 2.12109 6.78028 2.16797C6.75294 2.21435 6.74562 2.2705 6.76025 2.32275L7.36475 4.49367C7.38722 4.57474 7.35694 4.66067 7.28906 4.70999L5.91552 5.70756C5.87352 5.73734 5.82177 5.75052 5.77049 5.74368L4.31101 5.54249C4.23142 5.53174 4.16648 5.47512 4.14498 5.39796L3.50685 3.10504C3.47754 3.00104 3.3711 2.93804 3.26613 2.96391L2.89697 3.05426C2.87794 3.05913 2.86085 3.06891 2.84375 3.07916C2.41994 3.67339 2.20606 4.37117 2.20312 5.0699C2.20947 5.94687 2.54541 6.82188 3.21435 7.49082C4.02148 8.29748 5.12649 8.61389 6.17581 8.46592C6.32718 8.44395 6.46537 8.42879 6.59231 8.42001C6.7134 8.38679 6.83256 8.34335 6.95072 8.29598C8.41851 9.78233 15.631 17.1784 15.631 17.1784C16.1266 17.674 16.9298 17.674 17.4254 17.1784C17.921 16.6828 17.921 15.8796 17.4254 15.3839ZM16.9767 16.7297C16.7291 16.9777 16.3277 16.9777 16.0797 16.7297C15.8316 16.4821 15.8316 16.0802 16.0797 15.8322C16.3277 15.5846 16.7291 15.5846 16.9767 15.8322C17.2247 16.0802 17.2247 16.4821 16.9767 16.7297Z"
fill={isActive ? "var(--primary-color)" : "var(--text-color)"}
/>
<path
d="M14.6953 6.25784L16.1182 5.89699L17.4878 3.50488L16.8243 2.8755L16.1612 2.24609L13.8442 3.73926L13.5586 5.17824L11.0991 7.77054L12.2183 8.8682L14.6953 6.25784Z"
fill={isActive ? "var(--primary-color)" : "var(--text-color)"}
/>
<path
d="M7.56537 10.7632C7.28215 11.0083 6.8808 10.7046 6.35539 11.2588L2.88271 14.918C2.18837 15.6494 2.21865 16.8057 2.95009 17.5C3.68153 18.1944 4.83732 18.1641 5.53164 17.4327L9.00482 13.7725C9.53023 13.2188 9.20647 12.8345 9.43598 12.5386C9.48285 12.4776 9.52582 12.4356 9.56879 12.4038C8.91157 11.731 8.28266 11.0874 7.73821 10.5312C7.71528 10.6084 7.66303 10.6792 7.56537 10.7632Z"
fill={isActive ? "var(--primary-color)" : "var(--text-color)"}
/>
</svg>
);
}

View File

@ -1,8 +1,24 @@
import React from 'react';
import React, { useState } from "react";
import Search from "../../ui/inputs/Search";
const Assets: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>("");
const handleSearchChange = (value: string) => {
setSearchValue(value);
console.log(value); // Log the search value if needed
};
return (
<div>Assets</div>
<div className="assets-container">
<Search onChange={handleSearchChange} />
{searchValue ? (
<div className="searched-content">
<p>Results for "{searchValue}"</p>
</div>
) : (
<></>
)}
</div>
);
};

View File

@ -1,9 +1,29 @@
import React from 'react';
import React from "react";
import { ToggleSidebarIcon } from "../../icons/HeaderIcons";
import { LogoIcon } from "../../icons/Logo";
import FileMenu from "../../ui/FileMenu";
import useToggleStore from "../../../store/useUIToggleStore";
const Header: React.FC = () => {
const { toggleUI, setToggleUI } = useToggleStore();
return (
<div className="header-container">
<div className="header-content">
<div className="logo-container">
<LogoIcon />
</div>
<div className="header-title">
<FileMenu />
</div>
</div>
<div
className={`toggle-sidebar-ui-button ${!toggleUI ? "active" : ""}`}
onClick={() => {
setToggleUI(!toggleUI);
}}
>
<ToggleSidebarIcon />
</div>
</div>
);
};

View File

@ -1,8 +1,47 @@
import React from 'react';
import React, { useState } from "react";
import Search from "../../ui/inputs/Search";
import DropDownList from "../../ui/list/DropDownList";
const Outline: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>("");
const handleSearchChange = (value: string) => {
setSearchValue(value);
console.log(value); // Log the search value if needed
};
const dropdownItems = [
{ id: "1", name: "Ground Floor" },
{ id: "2", name: "Floor 1" },
]; // Example dropdown items
return (
<div>Outline</div>
<div className="outline-container">
<Search onChange={handleSearchChange} />
{searchValue ? (
<div className="searched-content">
<p>Results for "{searchValue}"</p>
</div>
) : (
<div className="outline-content-container">
<DropDownList
value="Layers"
items={dropdownItems}
defaultOpen={true}
showKebabMenu={false}
showFocusIcon={true}
/>
<DropDownList
value="Scene"
items={dropdownItems}
defaultOpen={true}
listType="outline"
showKebabMenu={false}
showAddIcon={false}
/>
</div>
)}
</div>
);
};

View File

@ -1,23 +1,53 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import ToggleHeader from "../../ui/inputs/ToggleHeader";
import Search from "../../ui/inputs/Search";
import Outline from "./Outline";
import Header from "./Header";
import useToggleStore from "../../../store/useUIToggleStore";
import Assets from "./Assets";
import useModuleStore from "../../../store/useModuleStore";
const SideBarLeft: React.FC = () => {
const [activeOption, setActiveOption] = useState("Option 1");
const [activeOption, setActiveOption] = useState("Outline");
const { toggleUI } = useToggleStore();
const { activeModule } = useModuleStore();
// Reset activeList whenever activeModule changes
useEffect(() => {
setActiveOption("Outline");
}, [activeModule]);
const handleToggleClick = (option: string) => {
setActiveOption(option); // Update the active option
};
return (
<>
<div>SideBarLeft</div>
<ToggleHeader
options={["Outline", "Assets"]}
activeOption={activeOption}
handleClick={handleToggleClick}
/>
<Search onChange={(value) => console.log(value)} />
</>
<div className="sidebar-left-wrapper">
<Header />
{toggleUI && (
<div className="sidebar-left-container">
{activeModule === "visualization" ? (
<>
<ToggleHeader
options={["Outline", "Widgets", "Templates"]}
activeOption={activeOption}
handleClick={handleToggleClick}
/>
</>
) : (
<>
<ToggleHeader
options={["Outline", "Assets"]}
activeOption={activeOption}
handleClick={handleToggleClick}
/>
<div className="sidebar-left-content-container">
{activeOption === "Outline" ? <Outline /> : <Assets />}
</div>
</>
)}
</div>
)}
</div>
);
};

View File

@ -0,0 +1,49 @@
import React from "react";
import { AppDockIcon } from "../../icons/HeaderIcons";
const Header: React.FC = () => {
const guestUsers = [
{ value: "Nazria", color: "#43C06D" },
{ value: "Name1", color: "#0050EB" },
{ value: "Abigail", color: "#FF6600" },
{ value: "Jack", color: "#488EF6" },
]; // Example guest users array
return (
<div className="header-container">
<div className="options-container">
<div className="share-button">Share</div>
<div className="app-docker-button">
<AppDockIcon />
</div>
</div>
<div className="split"></div>
<div className="users-container">
<div className="guest-users-container">
{guestUsers.length > 3 && (
<div className="other-guest">+{guestUsers.length - 3}</div>
)}
{guestUsers.slice(0, 3).map((user, index) => (
<div
key={index}
className="user-profile"
style={{ background: user.color }}
>
{user.value[0]}
</div>
))}
</div>
<div className="user-profile-container">
<div className="user-profile" style={{ background: "#48AC2A" }}>
V
</div>
<div className="user-organization">
<img src="" alt="" />
</div>
</div>
</div>
</div>
);
};
export default Header;

View File

@ -1,8 +1,67 @@
import React from 'react';
import React, { useEffect, useState } from "react";
import Header from "./Header";
import useModuleStore from "../../../store/useModuleStore";
import {
AnalysisIcon,
MechanicsIcon,
PropertiesIcon,
} from "../../icons/SimulationIcons";
import useToggleStore from "../../../store/useUIToggleStore";
import MachineMechanics from "./mechanics/MachineMechanics";
const SideBarRight: React.FC = () => {
const { activeModule } = useModuleStore();
const [activeList, setActiveList] = useState("properties");
const { toggleUI } = useToggleStore();
// Reset activeList whenever activeModule changes
useEffect(() => {
setActiveList("properties");
}, [activeModule]);
return (
<div>SideBarRight</div>
<div className="sidebar-right-wrapper">
<Header />
{toggleUI && (
<div className="sidebar-actions-container">
<div
className={`sidebar-action-list ${
activeList === "properties" ? "active" : ""
}`}
onClick={() => setActiveList("properties")}
>
<PropertiesIcon isActive={activeList === "properties"} />
</div>
{activeModule === "simulation" && (
<>
<div
className={`sidebar-action-list ${
activeList === "mechanics" ? "active" : ""
}`}
onClick={() => setActiveList("mechanics")}
>
<MechanicsIcon isActive={activeList === "mechanics"} />
</div>
<div
className={`sidebar-action-list ${
activeList === "analysis" ? "active" : ""
}`}
onClick={() => setActiveList("analysis")}
>
<AnalysisIcon isActive={activeList === "analysis"} />
</div>
</>
)}
</div>
)}
{toggleUI && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<MachineMechanics />
</div>
</div>
)}
</div>
);
};

View File

@ -0,0 +1,176 @@
import React, { useState } from "react";
import {
AddIcon,
InfoIcon,
RemoveIcon,
ResizeHeightIcon,
} from "../../../icons/ExportCommonIcons";
const MachineMechanics: React.FC = () => {
const [actionList, setActionList] = useState<string[]>([]);
const [triggerList, setTriggerList] = useState<string[]>([]);
const [selectedItem, setSelectedItem] = useState<{
type: "action" | "trigger";
name: string;
} | null>(null);
const [editedName, setEditedName] = useState<string>("");
const handleAddAction = () => {
setActionList([...actionList, `Action ${actionList.length + 1}`]);
};
const handleAddTrigger = () => {
setTriggerList([...triggerList, `Trigger ${triggerList.length + 1}`]);
};
const handleRemoveAction = (index: number) => {
setActionList(actionList.filter((_, i) => i !== index));
if (
selectedItem?.type === "action" &&
selectedItem.name === actionList[index]
) {
setSelectedItem(null);
setEditedName("");
}
};
const handleRemoveTrigger = (index: number) => {
setTriggerList(triggerList.filter((_, i) => i !== index));
if (
selectedItem?.type === "trigger" &&
selectedItem.name === triggerList[index]
) {
setSelectedItem(null);
setEditedName("");
}
};
const handleSelectItem = (type: "action" | "trigger", name: string) => {
setSelectedItem({ type, name });
setEditedName(name);
};
const handleSave = () => {
if (!selectedItem) return;
if (selectedItem.type === "action") {
setActionList(
actionList.map((action) =>
action === selectedItem.name ? editedName : action
)
);
} else if (selectedItem.type === "trigger") {
setTriggerList(
triggerList.map((trigger) =>
trigger === selectedItem.name ? editedName : trigger
)
);
}
setSelectedItem({ ...selectedItem, name: editedName });
};
return (
<div className="machine-mechanics-container">
<div className="actions">
<div className="header">
<div className="header-value">Actions</div>
<div className="add-button" onClick={handleAddAction}>
<AddIcon /> Add
</div>
</div>
<div className="lists-main-container">
<div className="list-container">
{actionList.map((action, index) => (
<div
key={index}
className={`list-item ${
selectedItem?.type === "action" && selectedItem.name === action
? "active"
: ""
}`}
>
<div className="value" onClick={() => handleSelectItem("action", action)}>
{action}
</div>
<div
className="remove-button"
onClick={() => handleRemoveAction(index)}
>
<RemoveIcon />
</div>
</div>
))}
</div>
<div className="resize-icon">
<ResizeHeightIcon />
</div>
</div>
</div>
<div className="triggers">
<div className="header">
<div className="header-value">Triggers</div>
<div className="add-button" onClick={handleAddTrigger}>
<AddIcon /> Add
</div>
</div>
<div className="lists-main-container">
<div className="list-container">
{triggerList.map((trigger, index) => (
<div
key={index}
className={`list-item ${
selectedItem?.type === "trigger" &&
selectedItem.name === trigger
? "active"
: ""
}`}
>
<div className="value" onClick={() => handleSelectItem("trigger", trigger)}>
{trigger}
</div>
<div
className="remove-button"
onClick={() => handleRemoveTrigger(index)}
>
<RemoveIcon />
</div>
</div>
))}
</div>
<div className="resize-icon">
<ResizeHeightIcon />
</div>
</div>
</div>
<div className="selected-properties-container">
{selectedItem && (
<>
<div>
<label>Edit Name:</label>
<input
type="text"
value={editedName}
onChange={(e) => setEditedName(e.target.value)}
/>
</div>
{/* Add other Properties Like:
* Object Selection Dropdown
* Buffer Time
* Get Value From Object
* Action
* etc.
*/}
<div onClick={handleSave}>Update</div> {/* remove this */}
</>
)}
</div>
<div className="footer">
<InfoIcon />
By Selecting Path, you can create Object Triggers.
</div>
</div>
);
};
export default MachineMechanics;

View File

@ -0,0 +1,9 @@
import React from "react";
const GlobalProperties: React.FC = () => {
return (
<div>GlobalProperties</div>
);
};
export default GlobalProperties;

View File

@ -0,0 +1,14 @@
import React from "react";
import RenameInput from "./inputs/RenameInput";
const FileMenu: React.FC = () => {
return (
<div className="project-dropdowm-container">
<div className="project-name">
<RenameInput value="untitled" />
</div>
</div>
);
};
export default FileMenu;

View File

@ -1,9 +0,0 @@
import React from 'react';
const ProjectDropDown: React.FC = () => {
return (
<div>ProjectDropDown</div>
);
};
export default ProjectDropDown;

View File

@ -0,0 +1,59 @@
import React, { useState, useRef } from "react";
interface RenameInputProps {
value: string;
onRename?: (newText: string) => void;
}
const RenameInput: React.FC<RenameInputProps> = ({ value, onRename }) => {
const [isEditing, setIsEditing] = useState(false);
const [text, setText] = useState(value);
const inputRef = useRef<HTMLInputElement | null>(null);
const handleDoubleClick = () => {
setIsEditing(true);
setTimeout(() => inputRef.current?.focus(), 0); // Focus the input after rendering
};
const handleBlur = () => {
setIsEditing(false);
if (onRename) {
onRename(text);
}
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setText(e.target.value);
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
setIsEditing(false);
if (onRename) {
onRename(text);
}
}
};
return (
<>
{isEditing ? (
<input
ref={inputRef}
type="text"
value={text}
onChange={handleChange}
onBlur={handleBlur}
onKeyDown={handleKeyDown}
className="rename-input"
/>
) : (
<span onDoubleClick={handleDoubleClick} className="input-value">
{text}
</span>
)}
</>
);
};
export default RenameInput;

View File

@ -1,5 +1,5 @@
import React, { ChangeEvent } from "react";
import { SearchIcon } from "../../icons/ExportCommonIcons";
import React, { ChangeEvent, useState } from "react";
import { CloseIcon, SearchIcon } from "../../icons/ExportCommonIcons";
interface SearchProps {
value?: string; // The current value of the search input
@ -8,25 +8,58 @@ interface SearchProps {
}
const Search: React.FC<SearchProps> = ({
value,
value = "",
placeholder = "Search",
onChange,
}) => {
// Handle input change
// State to track the input value and focus status
const [inputValue, setInputValue] = useState(value);
const [isFocused, setIsFocused] = useState(false);
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
onChange(event.target.value); // Call the onChange prop with the new value
const newValue = event.target.value;
setInputValue(newValue);
onChange(newValue); // Call the onChange prop with the new value
};
const handleClear = () => {
setInputValue("");
onChange(""); // Clear the input value
};
const handleFocus = () => {
setIsFocused(true); // Set focus state to true
};
const handleBlur = () => {
setIsFocused(false); // Set focus state to false
};
return (
<div className="search-container">
<SearchIcon />
<input
type="search"
className="search-input"
defaultValue={value}
placeholder={placeholder}
onChange={handleInputChange}
/>
<div className="search-wrapper">
<div
className={`search-container ${
isFocused || inputValue ? "active" : ""
}`}
>
<div className="icon-container">
<SearchIcon />
</div>
<input
type="text"
className="search-input"
value={inputValue}
placeholder={placeholder}
onChange={handleInputChange}
onFocus={handleFocus}
onBlur={handleBlur}
/>
{inputValue && (
<button className="clear-button" onClick={handleClear}>
<CloseIcon />
</button>
)}
</div>
</div>
);
};

View File

@ -0,0 +1,98 @@
import React, { useState } from "react";
import List from "./List";
import { AddIcon, ArrowIcon, FocusIcon } from "../../icons/ExportCommonIcons";
import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect";
interface DropDownListProps {
value?: string; // Value to display in the DropDownList
items?: { id: string; name: string }[]; // Items to display in the dropdown list
showFocusIcon?: boolean; // Determines if the FocusIcon should be displayed
showAddIcon?: boolean; // Determines if the AddIcon should be displayed
showKebabMenu?: boolean; // Determines if the KebabMenuList should be displayed
kebabMenuItems?: { id: string; name: string }[]; // Items for the KebabMenuList
defaultOpen?: boolean; // Determines if the dropdown list should be open by default
listType?: string; // Type of list to display
}
const DropDownList: React.FC<DropDownListProps> = ({
value = "Dropdown",
items = [],
showFocusIcon = false,
showAddIcon = true,
showKebabMenu = true,
kebabMenuItems = [
{ id: "Buildings", name: "Buildings" },
{ id: "Paths", name: "Paths" },
{ id: "Zones", name: "Zones" },
],
defaultOpen = false,
listType = "default",
}) => {
const [isOpen, setIsOpen] = useState<boolean>(defaultOpen);
const handleToggle = () => {
setIsOpen((prev) => !prev); // Toggle the state
};
return (
<div className="dropdown-list-container">
<div className="head">
<div className="value" onClick={handleToggle}>
{value}
</div>
<div className="options">
{showFocusIcon && (
<div className="focus option">
<FocusIcon />
</div>
)}
{showAddIcon && (
<div className="add option">
<AddIcon />
</div>
)}
{showKebabMenu && (
<div className="kebab-menu option">
<KebabMenuListMultiSelect items={kebabMenuItems} />
</div>
)}
<div
className="collapse-icon option"
style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }}
onClick={handleToggle}
>
<ArrowIcon />
</div>
</div>
</div>
{isOpen && (
<div className="lists-container">
{listType === "default" && <List items={items} />}
{listType === "outline" && (
<>
<DropDownList
value="Buildings"
showKebabMenu={false}
showAddIcon={false}
/>
<DropDownList
value="Zones"
showKebabMenu={false}
showAddIcon={false}
items={[]}
/>
<DropDownList
value="Paths"
showKebabMenu={false}
showAddIcon={false}
items={[]}
/>
</>
)}
</div>
)}
</div>
);
};
export default DropDownList;

View File

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

View File

@ -0,0 +1,82 @@
import React, { useEffect, useRef, useState } from "react";
import { KebebIcon, TickIcon } from "../../icons/ExportCommonIcons";
interface KebabMenuListMultiSelectProps {
items: { id: string; name: string }[]; // Array of menu items with id and name
onSelectionChange?: (selectedItems: string[]) => void; // Callback for selected items
}
const KebabMenuListMultiSelect: React.FC<KebabMenuListMultiSelectProps> = ({
items,
onSelectionChange,
}) => {
const [isOpen, setIsOpen] = useState(false);
const [selectedItems, setSelectedItems] = useState<string[]>([]);
const menuRef = useRef<HTMLDivElement>(null); // Ref to track the container
const handleToggle = () => {
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);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
return (
<div className="kebab-menu-container" ref={menuRef}>
<div className="kebab-icon" onClick={handleToggle}>
<KebebIcon />
</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>
);
};
export default KebabMenuListMultiSelect;

View File

@ -0,0 +1,45 @@
import React from "react";
import RenameInput from "../inputs/RenameInput";
import { EyeIcon, LockIcon, RmoveIcon } from "../../icons/ExportCommonIcons";
interface ListProps {
items?: { id: string; name: string }[]; // Optional array of items to render
placeholder?: string; // Optional placeholder text
}
const List: React.FC<ListProps> = ({ items = [] }) => {
return (
<>
{items.length > 0 ? (
<ul className="list-wrapper">
{items.map((item, index) => (
<li key={index} className="list-container">
<div className="list-item">
<div className="value">
<RenameInput value={item.name} />
</div>
<div className="options-container">
<div className="lock option">
<LockIcon isLocked />
</div>
<div className="visibe option">
<EyeIcon isClosed />
</div>
<div className="remove option">
<RmoveIcon />
</div>
</div>
</div>
</li>
))}
</ul>
) : (
<div className="list-wrapper">
<div className="no-item">No items to display</div>
</div>
)}
</>
);
};
export default List;

View File

@ -1,12 +1,14 @@
import React from 'react';
import ModuleToggle from '../components/ui/ModuleToggle';
import SideBarLeft from '../components/layout/sidebarLeft/SideBarLeft';
import SideBarRight from '../components/layout/sidebarRight/SideBarRight';
const Project: React.FC = () => {
return (
<div className="project-main">
<ModuleToggle />
<SideBarLeft />
<SideBarRight />
</div>
);
};

View File

@ -0,0 +1,13 @@
import { create } from "zustand";
interface ToggleState {
toggleUI: boolean; // State to track UI toggle
setToggleUI: (value: boolean) => void; // Action to update toggleUI
}
const useToggleStore = create<ToggleState>((set) => ({
toggleUI: true, // Initial state
setToggleUI: (value: boolean) => set({ toggleUI: value }), // Update the state
}));
export default useToggleStore;

View File

@ -40,6 +40,7 @@
--input-text-color: #{$input-text-color-dark}; // Input field text color
// Accent and Highlight colors
--primary-color: #{$highlight-accent-color-dark};
--accent-color: #{$accent-color-dark}; // Primary accent color for dark theme
--highlight-accent-color: #{$highlight-accent-color-dark}; // Highlight color for dark theme
@ -93,3 +94,28 @@ body {
--font-weight-medium: #{$medium-weight}; // Medium font weight
--font-weight-bold: #{$bold-weight}; // Bold font weight
}
/* Apply custom scrollbar styles globally */
::-webkit-scrollbar {
width: 8px; /* Width of the scrollbar */
height: 8px; /* Height for horizontal scrollbars */
}
::-webkit-scrollbar-track {
background: transparent; /* Background of the scrollbar track */
border-radius: 4px; /* Rounded corners */
}
::-webkit-scrollbar-thumb {
background: var(--accent-color); /* Scrollbar handle color */
border-radius: 4px; /* Rounded corners */
border: 2px solid #f4f4f4; /* Padding around the scrollbar handle */
}
::-webkit-scrollbar-thumb:hover {
background: var(--accent-color); /* Handle color on hover */
}
::-webkit-scrollbar-corner {
background: transparent; /* Remove corner styling for scrollable containers */
}

View File

@ -3,4 +3,5 @@
padding: 0;
box-sizing: border-box;
user-select: none;
font-size: var(--font-size-regular);
}

View File

@ -0,0 +1,151 @@
@use "../abstracts/variables" as *;
@use "../abstracts/mixins" as *;
.input-value {
color: var(--input-text-color);
font-size: var(--font-size-regular);
font-weight: var(--font-weight-regular);
display: block;
width: 100%;
height: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.rename-input {
width: 100%;
color: var(--input-text-color);
font-size: var(--font-size-regular);
font-weight: var(--font-weight-regular);
border: 1px solid var(--accent-color);
outline: none;
border-radius: #{$border-radius-small};
line-height: 26px;
padding: 0 8px;
}
.toggle-header-container {
@include flex-center;
padding: 6px 12px;
.toggle-header-item {
width: 100%;
text-align: center;
padding: 4px 12px;
border-radius: #{$border-radius-large};
}
.active {
background-color: var(--accent-color);
color: var(--primary-color);
}
}
.search-wrapper {
position: sticky;
top: 0;
padding: 8px 10px;
background: var(--background-color);
z-index: 1;
.search-container {
@include flex-center;
width: 100%;
border-radius: #{$border-radius-small};
background-color: var(--background-color);
padding: 6px 2px;
position: relative;
border: 1px solid var(--border-color);
.icon-container {
@include flex-center;
padding: 0 8px;
position: absolute;
width: fit-content;
left: 0;
}
.search-input {
width: 100%;
color: var(--input-text-color);
font-size: var(--font-size-regular);
font-weight: var(--font-weight-regular);
border: none;
outline: none;
background-color: transparent;
padding-left: 36px;
}
.clear-button {
@include flex-center;
position: absolute;
right: 4px;
width: 24px;
height: 24px;
border: none;
cursor: pointer;
background-color: transparent;
&:hover {
background-color: var(--highlight-accent-color);
}
}
}
.active {
border: 1px solid var(--accent-color);
}
}
.kebab-menu-container {
position: relative;
@include flex-center;
.kebab-icon {
@include flex-center;
}
.menu-list {
position: absolute;
left: 10px;
top: 12px;
background-color: var(--background-color);
border-radius: #{$border-radius-small};
box-shadow: var(--box-shadow-medium);
z-index: 1;
padding: 8px 4px;
width: 170px;
.menu-item {
margin: 2px 0;
padding: 2px 4px;
cursor: pointer;
border-radius: #{$border-radius-small};
display: flex;
gap: 2px;
&:hover {
background-color: var(--background-color-secondary);
}
.icon-container {
@include flex-center;
height: 18px;
width: 18px;
path {
stroke: var(--accent-color);
}
}
}
.selected {
background-color: var(--highlight-accent-color);
color: var(--accent-color);
&:hover {
background-color: var(--highlight-accent-color);
}
}
input {
display: none;
}
}
}
.project-dropdowm-container {
position: relative;
height: 32px;
.project-name{
line-height: 32px;
height: 100%;
}
}

View File

@ -0,0 +1,55 @@
@use "../abstracts/variables" as *;
@use "../abstracts/mixins" as *;
.dropdown-list-container {
border-bottom: 1px solid var(--border-color);
&:last-child {
border: none;
}
.head {
@include flex-space-between;
padding: 6px 12px;
.options {
@include flex-center;
gap: 6px;
.option {
@include flex-center;
cursor: pointer;
transition: all 0.2s;
}
}
}
}
.list-wrapper {
.no-item {
padding: 12px;
}
.list-container {
padding: 2px;
.list-item {
@include flex-space-between;
width: 100%;
text-align: center;
padding: 4px 12px;
border-radius: #{$border-radius-large};
.value {
width: 100%;
text-align: start;
max-width: 180px;
}
.options-container {
@include flex-center;
gap: 6px;
.option {
@include flex-center;
cursor: pointer;
}
}
}
.active {
background-color: var(--highlight-accent-color);
color: var(--primary-color);
}
}
}

View File

@ -1,10 +0,0 @@
@use "../abstracts/mixins" as mixins;
.flex {
@include mixins.flex-center;
gap: 14px;
}
.flex-sb {
@include mixins.flex-space-between;
gap: 4px;
}

View File

@ -0,0 +1,249 @@
@use "../abstracts/variables" as *;
@use "../abstracts/mixins" as *;
.sidebar-left-wrapper {
width: 270px;
position: fixed;
top: 32px;
left: 8px;
background-color: var(--background-color);
border-radius: #{$border-radius-extra-large};
box-shadow: #{$box-shadow-medium};
.header-container {
@include flex-space-between;
padding: 10px;
width: 100%;
.header-content {
@include flex-center;
width: calc(100% - 34px);
.logo-container {
@include flex-center;
}
.header-title {
padding: 0 8px;
width: 100%;
max-width: calc(100% - 32px);
.input-value {
color: var(--accent-color);
}
}
}
.toggle-sidebar-ui-button {
@include flex-center;
cursor: pointer;
height: 32px;
width: 32px;
min-height: 32px;
min-width: 32px;
border-radius: #{$border-radius-small};
&:hover {
background-color: var(--background-color-secondary);
}
}
.active {
background-color: var(--background-color-secondary);
outline: 1px solid var(--accent-color);
outline-offset: -1px;
}
}
.sidebar-left-container {
min-height: 50vh;
padding-bottom: 12px;
position: relative;
display: flex;
flex-direction: column;
.sidebar-left-content-container {
border-bottom: 1px solid var(--border-color);
// flex: 1;
height: calc(100% - 36px);
position: relative;
overflow: auto;
}
.outline-container {
height: 100%;
.outline-content-container {
position: relative;
height: 100%;
overflow: auto;
max-height: 60vh;
}
}
}
}
.sidebar-right-wrapper {
width: 320px;
position: fixed;
top: 32px;
right: 8px;
background-color: var(--background-color);
border-radius: #{$border-radius-extra-large};
box-shadow: #{$box-shadow-medium};
.header-container {
@include flex-space-between;
padding: 10px;
width: 100%;
gap: 12px;
height: 52px;
.options-container {
@include flex-center;
gap: 8px;
.share-button {
padding: 4px 12px;
color: var(--primary-color);
background-color: var(--accent-color);
font-weight: var(--font-weight-regular);
border-radius: #{$border-radius-medium};
cursor: pointer;
}
.app-docker-button {
@include flex-center;
}
}
.split {
height: 20px;
width: 2px;
background: var(--background-color-secondary);
}
.users-container {
width: 100%;
@include flex-space-between;
.user-profile {
@include flex-center;
height: 26px;
width: 26px;
min-height: 26px;
min-width: 26px;
border-radius: 50%;
font-weight: var(--font-weight-bold);
color: white;
}
.guest-users-container {
display: flex;
.other-guest {
@include flex-center;
height: 26px;
width: 26px;
min-height: 26px;
min-width: 26px;
border-radius: 50%;
background: var(--highlight-accent-color);
font-weight: var(--font-weight-bold);
color: var(--accent-color);
outline: 1px solid var(--accent-color);
outline-offset: -1px;
}
}
.user-profile-container {
display: flex;
.user-organnization {
height: 100%;
max-width: 52px;
img {
height: 100%;
width: 100%;
object-fit: cover;
}
}
}
}
}
.sidebar-actions-container {
position: absolute;
left: -40px;
.sidebar-action-list {
margin-bottom: 12px;
@include flex-center;
height: 34px;
width: 34px;
border-radius: #{$border-radius-circle};
background: var(--primary-color);
box-shadow: #{$box-shadow-medium};
}
.active {
background: var(--accent-color);
}
}
.sidebar-right-container {
min-height: 50vh;
padding-bottom: 12px;
position: relative;
display: flex;
flex-direction: column;
.sidebar-right-content-container {
border-bottom: 1px solid var(--border-color);
// flex: 1;
height: calc(100% - 36px);
position: relative;
overflow: auto;
}
}
}
.machine-mechanics-container {
.header {
@include flex-space-between;
padding: 6px 12px;
.add-button {
@include flex-center;
padding: 2px 4px;
background: var(--accent-color);
color: var(--primary-color);
border-radius: #{$border-radius-small};
cursor: pointer;
path {
stroke: var(--primary-color);
}
}
}
.lists-main-container {
margin: 2px 8px;
width: calc(100% - 16px);
background: var(--background-color-secondary);
border-radius: #{$border-radius-small};
.list-container {
min-height: 120px;
padding: 4px;
.list-item {
@include flex-space-between;
padding: 4px 12px;
width: 100%;
margin: 2px 0;
border-radius: #{$border-radius-small};
}
.active {
background: var(--accent-color);
.value {
color: var(--primary-color);
}
path {
stroke: var(--primary-color);
}
}
.remove-button {
@include flex-center;
height: 12px;
width: 12px;
cursor: pointer;
}
}
.resize-icon {
@include flex-center;
padding: 4px;
cursor: grab;
&:active {
cursor: grabbing;
}
}
}
.selected-properties-container {
padding: 12px;
}
.footer {
@include flex-center;
justify-content: flex-start;
gap: 4px;
padding: 12px;
font-size: var(--font-size-tiny);
}
}

View File

@ -11,18 +11,16 @@
// components
@use 'components/button';
@use 'components/form.scss';
@use 'components/form';
@use 'components/input';
@use 'components/layouts.scss';
@use 'components/moduleToggle.scss';
@use 'components/templates.scss';
@use 'components/tools.scss';
@use 'components/layouts';
@use 'components/lists';
@use 'components/moduleToggle';
@use 'components/templates';
@use 'components/tools';
// layout
@use 'layout/grid';
@use 'layout/header';
@use 'layout/aside';
@use 'layout/footer';
@use 'layout/sidebar';
// pages
@use 'pages/home';