Menu implementation

This commit is contained in:
Arnaud 2024-10-22 15:37:31 +02:00
parent 7ec8262953
commit 6b9c91f167
No known key found for this signature in database
GPG Key ID: 69D6CE281FCAE663
32 changed files with 1073 additions and 67 deletions

View File

@ -0,0 +1,30 @@
import { Menu } from "lucide-react";
import "./appBar.css";
import { ReactNode } from "react";
type Props = {
/**
* Event triggered when the menu is expanding, after a click on the
* menu button.
*/
onExpand: () => void;
/**
* React node to add to the right part of the application bar
*/
Right: ReactNode;
};
export function AppBar({ onExpand, Right }: Props) {
return (
<div className="appBar">
<div className="appBar-left">
<a className="appBar-burger" onClick={onExpand}>
<Menu size={"1.25rem"} />
</a>
<span>Home</span>
</div>
<div className="appBar-right">{Right}</div>
</div>
);
}

View File

@ -0,0 +1,32 @@
.appBar {
height: 40px;
justify-content: space-between;
border-bottom: 1px solid var(--codex-border-color);
view-transition-name: main-header;
display: flex;
padding: 0.75rem 1.5rem;
}
.appBar-burger {
cursor: pointer;
color: var(--codex-color);
display: flex;
}
.appBar,
.appBar-left,
.appBar-right {
display: flex;
align-items: center;
}
.appBar-left,
.appBar-right {
gap: 0.75rem;
}
@media (min-width: 1000px) {
.appBar-burger {
display: none;
}
}

View File

@ -0,0 +1,40 @@
export function Logo() {
return (
<svg
width="30"
height="34"
viewBox="0 0 30 34"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M15.2342 1.43459L14.9745 1.27686L14.7149 1.43477L0.989288 9.78295L0.749113 9.92903L0.749113 10.2101L0.749112 23.7179L0.749112 23.9969L0.98663 24.1434L14.6387 32.5639L14.8995 32.7247L15.1611 32.5654L28.9813 24.1553L29.2213 24.0092L29.2213 23.7282L29.2213 10.2101L29.2213 9.9288L28.9809 9.78277L15.2342 1.43459ZM14.9747 3.31423L27.4337 10.9038L27.4337 23.035L14.9129 30.6848L2.51571 23.0364L2.51571 10.9038L14.9747 3.31423Z"
fill="var(--codex-color-primary)"
stroke="var(--codex-color-primary)"
/>
<path
d="M14.5966 31.705L15.3422 31.705L15.3422 2.23351L14.5966 2.23351L14.5966 31.705Z"
fill="var(--codex-color-primary)"
/>
<path
d="M21.2337 27.577L21.9793 27.577L21.9793 6.35054L21.2337 6.35054L21.2337 27.577Z"
fill="var(--codex-color-primary)"
/>
<path
d="M7.90706 27.577L8.65267 27.577L8.65267 6.35054L7.90706 6.35054L7.90706 27.577Z"
fill="var(--codex-color-primary)"
/>
<path
d="M8.46544 28.0195L28.4616 17.4088L28.1073 16.7641L8.11114 27.3748L8.46544 28.0195Z"
fill="var(--codex-color-primary)"
/>
<path
d="M1.79454 24.0028L28.4599 10.8989L28.1264 10.2436L1.46103 23.3475L1.79454 24.0028Z"
fill="var(--codex-color-primary)"
/>
<path
d="M21.4216 27.9492L21.7759 27.3045L1.77983 16.6938L1.42553 17.3385L21.4216 27.9492Z"
fill="var(--codex-color-primary)"
/>
</svg>
);
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
export function AnalyticsIcon() {
return (
<svg
width="15"
height="14"
viewBox="0 0 15 14"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M1.75 0.25V12.25H13.75V13.75H0.25V0.25H1.75ZM12.955 2.455L14.545 4.045L10 8.5915L7.75 6.3415L4.795 9.2965L3.205 7.705L7.75 3.16L10 5.41L12.955 2.455Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function DeviceIcon() {
return (
<svg
width="14"
height="16"
viewBox="0 0 14 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M13 0.5C13.414 0.5 13.75 0.836 13.75 1.25V14.75C13.75 15.164 13.414 15.5 13 15.5H2.5C2.086 15.5 1.75 15.164 1.75 14.75V13.25H0.25V11.75H1.75V10.25H0.25V8.75H1.75V7.25H0.25V5.75H1.75V4.25H0.25V2.75H1.75V1.25C1.75 0.836 2.086 0.5 2.5 0.5H13ZM12.25 2H3.25V14H12.25V2ZM8.5 5V7.25H10.75V8.75H8.49925L8.5 11H7L6.99925 8.75H4.75V7.25H7V5H8.5Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function DisclaimerIcon() {
return (
<svg
width="14"
height="16"
viewBox="0 0 14 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M9.25 2H1.75V14H12.25V5H9.25V2ZM0.25 1.244C0.25 0.833 0.58525 0.5 0.99925 0.5H10L13.75 4.25V14.7448C13.7507 14.8432 13.732 14.9409 13.6949 15.0322C13.6579 15.1234 13.6032 15.2065 13.534 15.2766C13.4649 15.3468 13.3826 15.4026 13.2919 15.4409C13.2011 15.4792 13.1037 15.4993 13.0052 15.5H0.99475C0.797784 15.4986 0.609263 15.4198 0.469913 15.2806C0.330563 15.1414 0.251571 14.953 0.25 14.756V1.244ZM6.25 10.25H7.75V11.75H6.25V10.25ZM6.25 4.25H7.75V8.75H6.25V4.25Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,27 @@
type Props = {
onClick?: () => void;
};
export function ExpandIcon({ onClick }: Props) {
return (
<svg
onClick={onClick}
height="20"
viewBox="0 0 17 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<rect
x="1.45746"
y="0.5"
width="15"
height="15"
rx="4.5"
stroke="#515151"
/>
<path
d="M8.07651 3.88107L8.07646 7.44461L11.1798 7.44466V8.55577L8.07646 8.55572L8.0764 12.1191L3.95746 8.00011L8.07651 3.88107ZM12.2909 11.889V4.11121H13.402V11.889H12.2909Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function FilesIcon() {
return (
<svg
width="16"
height="14"
viewBox="0 0 16 14"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M3.5 3.25V1C3.5 0.801088 3.57902 0.610322 3.71967 0.46967C3.86032 0.329018 4.05109 0.25 4.25 0.25H9.0605L10.5605 1.75H14.75C14.9489 1.75 15.1397 1.82902 15.2803 1.96967C15.421 2.11032 15.5 2.30109 15.5 2.5V10C15.5 10.1989 15.421 10.3897 15.2803 10.5303C15.1397 10.671 14.9489 10.75 14.75 10.75H12.5V13C12.5 13.1989 12.421 13.3897 12.2803 13.5303C12.1397 13.671 11.9489 13.75 11.75 13.75H1.25C1.05109 13.75 0.860322 13.671 0.71967 13.5303C0.579018 13.3897 0.5 13.1989 0.5 13V4C0.5 3.80109 0.579018 3.61032 0.71967 3.46967C0.860322 3.32902 1.05109 3.25 1.25 3.25H3.5ZM3.5 4.75H2V12.25H11V10.75H3.5V4.75Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function HelpIcon() {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M8 15.5C3.85775 15.5 0.5 12.1423 0.5 8C0.5 3.85775 3.85775 0.5 8 0.5C12.1423 0.5 15.5 3.85775 15.5 8C15.5 12.1423 12.1423 15.5 8 15.5ZM8 14C9.5913 14 11.1174 13.3679 12.2426 12.2426C13.3679 11.1174 14 9.5913 14 8C14 6.4087 13.3679 4.88258 12.2426 3.75736C11.1174 2.63214 9.5913 2 8 2C6.4087 2 4.88258 2.63214 3.75736 3.75736C2.63214 4.88258 2 6.4087 2 8C2 9.5913 2.63214 11.1174 3.75736 12.2426C4.88258 13.3679 6.4087 14 8 14ZM7.25 10.25H8.75V11.75H7.25V10.25ZM8.75 9.01625V9.5H7.25V8.375C7.25 8.17609 7.32902 7.98532 7.46967 7.84467C7.61032 7.70402 7.80109 7.625 8 7.625C8.21306 7.62499 8.42173 7.56447 8.60174 7.4505C8.78175 7.33652 8.9257 7.17377 9.01683 6.98119C9.10796 6.7886 9.14253 6.5741 9.11651 6.36263C9.0905 6.15117 9.00497 5.95144 8.86987 5.78668C8.73478 5.62193 8.55568 5.49892 8.35342 5.43198C8.15115 5.36503 7.93403 5.3569 7.72732 5.40853C7.52061 5.46016 7.33281 5.56942 7.18577 5.72361C7.03874 5.8778 6.93851 6.07057 6.89675 6.2795L5.42525 5.98475C5.51647 5.52881 5.72713 5.10528 6.03569 4.75744C6.34425 4.4096 6.73964 4.14994 7.18144 4.00499C7.62325 3.86004 8.09561 3.83501 8.55026 3.93246C9.00491 4.02991 9.42553 4.24634 9.76911 4.55962C10.1127 4.8729 10.3669 5.2718 10.5058 5.71555C10.6447 6.15929 10.6633 6.63196 10.5596 7.08523C10.456 7.5385 10.2338 7.95612 9.91589 8.2954C9.59794 8.63467 9.1956 8.88343 8.75 9.01625Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function HomeIcon() {
return (
<svg
width="16"
height="14"
viewBox="0 0 16 14"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M15.5 5.49925V13C15.5 13.1989 15.421 13.3897 15.2803 13.5303C15.1397 13.671 14.9489 13.75 14.75 13.75H8.75V5.49925H15.5ZM7.25 9.99925V13.75H1.25C1.05109 13.75 0.860322 13.671 0.71967 13.5303C0.579018 13.3897 0.5 13.1989 0.5 13V9.99925H7.25ZM7.25 0.25V8.49925H0.5V1C0.5 0.801088 0.579018 0.610322 0.71967 0.46967C0.860322 0.329018 1.05109 0.25 1.25 0.25H7.25ZM14.75 0.25C14.9489 0.25 15.1397 0.329018 15.2803 0.46967C15.421 0.610322 15.5 0.801088 15.5 1V3.99925H8.75V0.25H14.75Z"
fill="var(--codex-color-primary)"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function HostIcon() {
return (
<svg
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M1.75 6.25H12.25V1.75H1.75V6.25ZM13.75 1V13C13.75 13.1989 13.671 13.3897 13.5303 13.5303C13.3897 13.671 13.1989 13.75 13 13.75H1C0.801088 13.75 0.610322 13.671 0.46967 13.5303C0.329018 13.3897 0.25 13.1989 0.25 13V1C0.25 0.801088 0.329018 0.610322 0.46967 0.46967C0.610322 0.329018 0.801088 0.25 1 0.25H13C13.1989 0.25 13.3897 0.329018 13.5303 0.46967C13.671 0.610322 13.75 0.801088 13.75 1ZM12.25 7.75H1.75V12.25H12.25V7.75ZM3.25 9.25H5.5V10.75H3.25V9.25ZM3.25 3.25H5.5V4.75H3.25V3.25Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function LogsIcon() {
return (
<svg
width="14"
height="16"
viewBox="0 0 14 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M13 15.5H1C0.801088 15.5 0.610322 15.421 0.46967 15.2803C0.329018 15.1397 0.25 14.9489 0.25 14.75V1.25C0.25 1.05109 0.329018 0.860322 0.46967 0.71967C0.610322 0.579018 0.801088 0.5 1 0.5H13C13.1989 0.5 13.3897 0.579018 13.5303 0.71967C13.671 0.860322 13.75 1.05109 13.75 1.25V14.75C13.75 14.9489 13.671 15.1397 13.5303 15.2803C13.3897 15.421 13.1989 15.5 13 15.5ZM12.25 14V2H1.75V14H12.25ZM4 5.75H10V7.25H4V5.75ZM4 8.75H10V10.25H4V8.75Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,114 @@
import { Backdrop } from "@codex-storage/marketplace-ui-components";
import { attributes } from "../../utils/attributes";
import "./menu.css";
import { ComponentType, useEffect, useState } from "react";
import { Logo } from "../Logo/Logo";
import { Logotype } from "../Logotype/Logotype";
import { ExpandIcon } from "./ExpandIcon";
import { classnames } from "../../utils/classnames";
export type MenuItemComponentProps = {
onClick: () => void;
className: string;
};
export type MenuItem =
| {
type: "separator";
}
| {
type: "space";
}
| {
type: "empty";
}
| {
type: "item";
Component: ComponentType<MenuItemComponentProps>;
};
type Props = {
/**
* If true, the menu will be displayed
*/
expanded: boolean;
onClose: () => void;
onOpen?: () => void;
/**
* The menu items to be displayed
*/
items: MenuItem[];
className?: string;
/**
* The application version
*/
version?: string;
};
export function Menu({
expanded,
onClose,
onOpen,
items,
className = "",
}: Props) {
const [isExpanded, setIsExpanded] = useState(true);
useEffect(() => {
if (expanded && onOpen) {
onOpen();
}
}, [expanded, onOpen]);
const onExpandMenu = () => setIsExpanded(!isExpanded);
const renderItem = (i: MenuItem, index: number) => {
switch (i.type) {
case "separator":
return <hr className="menu-item-separator" key={index}></hr>;
case "space":
return <div className="menu-space" key={index}></div>;
case "empty":
return <div className="menu-empty" key={index}></div>;
case "item":
return (
<i.Component onClick={onClose} className="menu-item" key={index} />
);
}
};
return (
<>
<Backdrop onClose={onClose} open={expanded} />
<aside
className={classnames(
[`menu ${className}`],
["menu--expanded", isExpanded]
)}
{...attributes({ "aria-expanded": expanded })}>
<div className="menu-container">
<div className="menu-header">
<Logo />
<Logotype height={34} className={"menu-logotype"} />
<div className="menu-header-right">
<ExpandIcon onClick={onExpandMenu}></ExpandIcon>
</div>
{/* <span className="menu-separator">|</span>
<span className="menu-name">Codex</span>
<span className="menu-state">ALPHA {version}</span> */}
</div>
<div className="menu-items">
{items.map((item, index) => renderItem(item, index))}
</div>
</div>
</aside>
</>
);
}

View File

@ -0,0 +1,15 @@
export function NodesIcon() {
return (
<svg
width="14"
height="16"
viewBox="0 0 14 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M5.5 0.5C5.914 0.5 6.25 0.836 6.25 1.25V4.25C6.25 4.664 5.914 5 5.5 5H4V6.5H7.75V5.75C7.75 5.336 8.086 5 8.5 5H13C13.414 5 13.75 5.336 13.75 5.75V8.75C13.75 9.164 13.414 9.5 13 9.5H8.5C8.086 9.5 7.75 9.164 7.75 8.75V8H4V12.5H7.75V11.75C7.75 11.336 8.086 11 8.5 11H13C13.414 11 13.75 11.336 13.75 11.75V14.75C13.75 15.164 13.414 15.5 13 15.5H8.5C8.086 15.5 7.75 15.164 7.75 14.75V14H3.25C2.836 14 2.5 13.664 2.5 13.25V5H1C0.586 5 0.25 4.664 0.25 4.25V1.25C0.25 0.836 0.586 0.5 1 0.5H5.5ZM12.25 12.5H9.25V14H12.25V12.5ZM12.25 6.5H9.25V8H12.25V6.5ZM4.75 2H1.75V3.5H4.75V2Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function PeersIcon() {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M8 15.5C3.85775 15.5 0.5 12.1422 0.5 8C0.5 3.85775 3.85775 0.5 8 0.5C12.1422 0.5 15.5 3.85775 15.5 8C15.5 12.1422 12.1422 15.5 8 15.5ZM6.2825 13.7502C5.54256 12.1807 5.1139 10.4827 5.02025 8.75H2.0465C2.19244 9.90417 2.67044 10.9911 3.42243 11.8788C4.17441 12.7664 5.16801 13.4166 6.2825 13.7502ZM6.5225 8.75C6.63575 10.5792 7.1585 12.2975 8 13.814C8.86424 12.2574 9.36908 10.5271 9.4775 8.75H6.5225ZM13.9535 8.75H10.9797C10.8861 10.4827 10.4574 12.1807 9.7175 13.7502C10.832 13.4166 11.8256 12.7664 12.5776 11.8788C13.3296 10.9911 13.8076 9.90417 13.9535 8.75ZM2.0465 7.25H5.02025C5.1139 5.51734 5.54256 3.81926 6.2825 2.24975C5.16801 2.58341 4.17441 3.23356 3.42243 4.12122C2.67044 5.00888 2.19244 6.09583 2.0465 7.25ZM6.52325 7.25H9.47675C9.36856 5.47295 8.86398 3.74265 8 2.186C7.13576 3.74259 6.63092 5.47289 6.5225 7.25H6.52325ZM9.7175 2.24975C10.4574 3.81926 10.8861 5.51734 10.9797 7.25H13.9535C13.8076 6.09583 13.3296 5.00888 12.5776 4.12122C11.8256 3.23356 10.832 2.58341 9.7175 2.24975Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,22 @@
export function PurchaseIcon() {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#clip0_103_62)">
<path
d="M4.8 6.9726L1.8813 4.0548L3.1548 2.7813L6.0726 5.7H19.7904C19.9307 5.69999 20.069 5.73278 20.1944 5.79573C20.3197 5.85869 20.4287 5.95008 20.5124 6.06261C20.5962 6.17514 20.6525 6.30569 20.6768 6.44384C20.7012 6.58199 20.6929 6.72392 20.6526 6.8583L18.4926 14.0583C18.437 14.2438 18.3231 14.4064 18.1678 14.522C18.0125 14.6376 17.824 14.7 17.6304 14.7H6.6V16.5H16.5V18.3H5.7C5.46131 18.3 5.23239 18.2052 5.06361 18.0364C4.89482 17.8676 4.8 17.6387 4.8 17.4V6.9726ZM6.6 7.5V12.9H16.9608L18.5808 7.5H6.6ZM6.15 21.9C5.79196 21.9 5.44858 21.7578 5.19541 21.5046C4.94223 21.2514 4.8 20.908 4.8 20.55C4.8 20.192 4.94223 19.8486 5.19541 19.5954C5.44858 19.3422 5.79196 19.2 6.15 19.2C6.50804 19.2 6.85142 19.3422 7.1046 19.5954C7.35777 19.8486 7.5 20.192 7.5 20.55C7.5 20.908 7.35777 21.2514 7.1046 21.5046C6.85142 21.7578 6.50804 21.9 6.15 21.9ZM16.95 21.9C16.592 21.9 16.2486 21.7578 15.9954 21.5046C15.7422 21.2514 15.6 20.908 15.6 20.55C15.6 20.192 15.7422 19.8486 15.9954 19.5954C16.2486 19.3422 16.592 19.2 16.95 19.2C17.308 19.2 17.6514 19.3422 17.9046 19.5954C18.1578 19.8486 18.3 20.192 18.3 20.55C18.3 20.908 18.1578 21.2514 17.9046 21.5046C17.6514 21.7578 17.308 21.9 16.95 21.9Z"
fill="#969696"
/>
</g>
<defs>
<clipPath id="clip0_103_62">
<rect width="20" height="20" fill="white" />
</clipPath>
</defs>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function SettingsIcon() {
return (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M6.5145 3L8.46975 1.04475C8.6104 0.904151 8.80113 0.825165 9 0.825165C9.19887 0.825165 9.3896 0.904151 9.53025 1.04475L11.4855 3H14.25C14.4489 3 14.6397 3.07902 14.7803 3.21967C14.921 3.36033 15 3.55109 15 3.75V6.5145L16.9552 8.46975C17.0959 8.6104 17.1748 8.80113 17.1748 9C17.1748 9.19888 17.0959 9.38961 16.9552 9.53025L15 11.4855V14.25C15 14.4489 14.921 14.6397 14.7803 14.7803C14.6397 14.921 14.4489 15 14.25 15H11.4855L9.53025 16.9553C9.3896 17.0959 9.19887 17.1748 9 17.1748C8.80113 17.1748 8.6104 17.0959 8.46975 16.9553L6.5145 15H3.75C3.55109 15 3.36032 14.921 3.21967 14.7803C3.07902 14.6397 3 14.4489 3 14.25V11.4855L1.04475 9.53025C0.904148 9.38961 0.825161 9.19888 0.825161 9C0.825161 8.80113 0.904148 8.6104 1.04475 8.46975L3 6.5145V3.75C3 3.55109 3.07902 3.36033 3.21967 3.21967C3.36032 3.07902 3.55109 3 3.75 3H6.5145ZM4.5 4.5V7.13625L2.63625 9L4.5 10.8638V13.5H7.13625L9 15.3638L10.8638 13.5H13.5V10.8638L15.3637 9L13.5 7.13625V4.5H10.8638L9 2.63625L7.13625 4.5H4.5ZM9 12C8.20435 12 7.44129 11.6839 6.87868 11.1213C6.31607 10.5587 6 9.79565 6 9C6 8.20435 6.31607 7.44129 6.87868 6.87868C7.44129 6.31607 8.20435 6 9 6C9.79565 6 10.5587 6.31607 11.1213 6.87868C11.6839 7.44129 12 8.20435 12 9C12 9.79565 11.6839 10.5587 11.1213 11.1213C10.5587 11.6839 9.79565 12 9 12ZM9 10.5C9.39782 10.5 9.77936 10.342 10.0607 10.0607C10.342 9.77936 10.5 9.39783 10.5 9C10.5 8.60218 10.342 8.22065 10.0607 7.93934C9.77936 7.65804 9.39782 7.5 9 7.5C8.60218 7.5 8.22064 7.65804 7.93934 7.93934C7.65804 8.22065 7.5 8.60218 7.5 9C7.5 9.39783 7.65804 9.77936 7.93934 10.0607C8.22064 10.342 8.60218 10.5 9 10.5Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,15 @@
export function WalletIcon() {
return (
<svg
width="16"
height="14"
viewBox="0 0 16 14"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M1.25 0.25H14.75C14.9489 0.25 15.1397 0.329018 15.2803 0.46967C15.421 0.610322 15.5 0.801088 15.5 1V13C15.5 13.1989 15.421 13.3897 15.2803 13.5303C15.1397 13.671 14.9489 13.75 14.75 13.75H1.25C1.05109 13.75 0.860322 13.671 0.71967 13.5303C0.579018 13.3897 0.5 13.1989 0.5 13V1C0.5 0.801088 0.579018 0.610322 0.71967 0.46967C0.860322 0.329018 1.05109 0.25 1.25 0.25ZM14 6.25H2V12.25H14V6.25ZM14 4.75V1.75H2V4.75H14ZM9.5 9.25H12.5V10.75H9.5V9.25Z"
fill="#969696"
/>
</svg>
);
}

View File

@ -0,0 +1,225 @@
.menu {
display: flex;
flex-direction: column;
background-color: #1c1c1c;
border-radius: var(--codex-border-radius);
transform: translatex(-500px);
transition: transform 0.25s;
position: fixed;
z-index: 10;
view-transition-name: main-menu;
height: 100%;
top: 0;
left: 0;
width: 75px;
transition: width 0.5s;
min-width: 75px;
}
.menu--expanded {
width: 272px;
}
.menu:not(.menu--expanded) .menu-text,
.menu:not(.menu--expanded) .menu-logotype,
.menu:not(.menu--expanded) .menu-header-right {
display: none;
}
.menu-container {
display: flex;
flex-direction: column;
flex: 1;
padding: 12px;
}
.menu-header-right {
flex: 1;
text-align: right;
transition: opacity 0.35s;
cursor: pointer;
}
.menu-header-right:hover {
animation-name: example;
animation-duration: 2.5s;
animation-iteration-count: infinite;
}
.menu-backdrop {
display: none;
}
.menu-items {
border-top: 2px solid var(--codex-border-color);
padding-top: 1.5rem;
flex: 1;
display: flex;
flex-direction: column;
position: relative;
}
.menu[aria-expanded] {
transform: translatex(0);
min-width: 200px;
}
.menu-header {
padding: 12px;
display: flex;
align-items: center;
gap: 1.5rem;
margin-bottom: 1rem;
background-color: #060606;
border-radius: 8px;
}
.menu-item {
display: flex;
align-items: center;
gap: 0.75rem;
}
.menu-items::before {
height: 20px;
width: 8px;
background-color: var(--codex-color-primary);
position: absolute;
content: " ";
transition:
top 1s,
bottom 1s;
border-radius: 4px;
left: -16px;
}
.menu-items:has(.active:nth-child(1))::before {
top: 30px;
}
.menu-items:has(.active:nth-child(2))::before {
top: 72px;
}
.menu-items:has(.active:nth-child(3))::before {
top: 115px;
}
.menu-items:has(.active:nth-child(4))::before {
top: 158px;
}
.menu-items:has(.active:nth-child(5))::before {
top: 201px;
}
.menu-items:has(.active:nth-child(6))::before {
top: 244px;
}
.menu-items:has(.active:nth-child(8))::before {
top: 332px;
}
.menu-items:has(.active:nth-child(9))::before {
top: 375px;
}
.menu-items:has(.active:nth-child(11))::before {
top: 461px;
}
.menu-items:has(.active:nth-child(12))::before {
top: 504px;
}
.menu-items:has(.active:nth-child(14))::before {
bottom: 133px;
}
.menu-items:has(.active:nth-child(15))::before {
bottom: 90px;
}
.menu-items:has(.active:nth-child(16))::before {
bottom: 47px;
}
.menu-item:not(:first-child) {
margin-top: 0.5rem;
}
.menu-item {
padding: 8px 16px;
margin-bottom: 0;
text-decoration: none;
font-size: 14px;
font-weight: 500;
line-height: 20px;
letter-spacing: -0.006em;
color: #969696;
border-radius: 8px;
transition: background-color 0.35s;
}
.menu-item:hover,
.menu-item.active {
background-color: var(--codex-highlight-color);
color: #c7c7c7;
}
.menu-title {
text-transform: uppercase;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
padding-left: 0.75rem;
display: inline-block;
font-weight: 500;
}
.menu-item-separator {
margin-top: 1.5rem;
margin-bottom: 1.5rem;
border: 0.1px solid var(--codex-border-color);
width: 100%;
}
.menu-state {
font-size: 0.6rem;
background-color: var(--codex-background-light);
padding: 0.25rem;
border-radius: var(--codex-border-radius);
position: relative;
top: 1px;
}
.menu-footer {
text-align: center;
}
.menu-version {
padding: 0;
}
.menu-space {
flex: 1;
}
.menu-empty {
height: 40px;
}
.menu-icon {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
}
@media (min-width: 1000px) {
.menu {
transform: translatex(0px);
position: inherit;
}
}

View File

@ -4,7 +4,6 @@ import "./OnBoardingStepThree.css";
import { usePortForwarding } from "../../hooks/usePortForwarding";
import { useCodexConnection } from "../../hooks/useCodexConnection";
import {
Button,
ButtonIcon,
Input,
SimpleText,

View File

@ -0,0 +1,37 @@
import { ReactNode, useState } from "react";
import { Menu, MenuItem } from "../Menu/Menu";
import { AppBar } from "../AppBar/AppBar";
import "./page.css";
type Props = {
children: ReactNode;
Right: ReactNode;
items: MenuItem[];
version?: string;
};
export function Page({ children, Right, items, version = "" }: Props) {
const [open, setOpen] = useState(false);
const onClose = () => setOpen(false);
const onExpand = () => setOpen(true);
return (
<div className="page">
<Menu
expanded={open}
onClose={onClose}
items={items}
version={version}></Menu>
<main className="page-main">
<AppBar onExpand={onExpand} Right={Right} />
{children}
</main>
</div>
);
}

View File

@ -0,0 +1,8 @@
.page {
display: flex;
flex: 1;
}
.page-main {
flex: 1;
}

View File

@ -15,7 +15,7 @@
}
:root {
--codex-background: rgb(23 23 23);
--codex-background: #1c1c1c;
--codex-color: white;
--codex-color-contrast: #f8f8f8;
--codex-color-error: 204, 108, 108;
@ -24,14 +24,15 @@
--codex-color-success: 20, 184, 166;
--codex-color-blue: 30, 64, 175;
--codex-color-grey: 170, 170, 170;
--codex-color-primary: #6ccc93;
--codex-color-primary: #6fcb94;
--codex-color-primary-rgb: 193, 240, 164;
--codex-color-primary-variant: #c1f0a4cc;
--codex-color-on-primary: #333;
--codex-color-disabled: #717171;
--codex-color-light: rgb(150 150 150);
--codex-border-color: rgb(82 82 82);
--codex-border-color: #2b303b;
--codex-background-secondary: rgb(38 38 38);
--codex-highlight-color: #2f2f2f;
--codex-background-light: rgb(64 64 64);
--codex-background-backdrop: rgba(70, 70, 70, 0.75);
--codex-border-radius: 0.5rem;

View File

@ -14,74 +14,128 @@ import { Route as rootRoute } from './routes/__root'
import { Route as DashboardImport } from './routes/dashboard'
import { Route as IndexImport } from './routes/index'
import { Route as DashboardIndexImport } from './routes/dashboard/index'
import { Route as DashboardWalletImport } from './routes/dashboard/wallet'
import { Route as DashboardSettingsImport } from './routes/dashboard/settings'
import { Route as DashboardRequestsImport } from './routes/dashboard/requests'
import { Route as DashboardPurchasesImport } from './routes/dashboard/purchases'
import { Route as DashboardPeersImport } from './routes/dashboard/peers'
import { Route as DashboardNodesImport } from './routes/dashboard/nodes'
import { Route as DashboardLogsImport } from './routes/dashboard/logs'
import { Route as DashboardHelpImport } from './routes/dashboard/help'
import { Route as DashboardFilesImport } from './routes/dashboard/files'
import { Route as DashboardFavoritesImport } from './routes/dashboard/favorites'
import { Route as DashboardDisclaimerImport } from './routes/dashboard/disclaimer'
import { Route as DashboardDeviceImport } from './routes/dashboard/device'
import { Route as DashboardAvailabilitiesImport } from './routes/dashboard/availabilities'
import { Route as DashboardAnalyticsImport } from './routes/dashboard/analytics'
import { Route as DashboardAboutImport } from './routes/dashboard/about'
// Create/Update Routes
const DashboardRoute = DashboardImport.update({
id: '/dashboard',
path: '/dashboard',
getParentRoute: () => rootRoute,
} as any)
const IndexRoute = IndexImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRoute,
} as any)
const DashboardIndexRoute = DashboardIndexImport.update({
id: '/',
path: '/',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardWalletRoute = DashboardWalletImport.update({
id: '/wallet',
path: '/wallet',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardSettingsRoute = DashboardSettingsImport.update({
id: '/settings',
path: '/settings',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardRequestsRoute = DashboardRequestsImport.update({
id: '/requests',
path: '/requests',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardPurchasesRoute = DashboardPurchasesImport.update({
id: '/purchases',
path: '/purchases',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardPeersRoute = DashboardPeersImport.update({
id: '/peers',
path: '/peers',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardNodesRoute = DashboardNodesImport.update({
id: '/nodes',
path: '/nodes',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardLogsRoute = DashboardLogsImport.update({
id: '/logs',
path: '/logs',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardHelpRoute = DashboardHelpImport.update({
id: '/help',
path: '/help',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardFilesRoute = DashboardFilesImport.update({
id: '/files',
path: '/files',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardFavoritesRoute = DashboardFavoritesImport.update({
id: '/favorites',
path: '/favorites',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardDisclaimerRoute = DashboardDisclaimerImport.update({
id: '/disclaimer',
path: '/disclaimer',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardDeviceRoute = DashboardDeviceImport.update({
id: '/device',
path: '/device',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardAvailabilitiesRoute = DashboardAvailabilitiesImport.update({
id: '/availabilities',
path: '/availabilities',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardAnalyticsRoute = DashboardAnalyticsImport.update({
id: '/analytics',
path: '/analytics',
getParentRoute: () => DashboardRoute,
} as any)
const DashboardAboutRoute = DashboardAboutImport.update({
id: '/about',
path: '/about',
getParentRoute: () => DashboardRoute,
} as any)
@ -111,6 +165,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DashboardAboutImport
parentRoute: typeof DashboardImport
}
'/dashboard/analytics': {
id: '/dashboard/analytics'
path: '/analytics'
fullPath: '/dashboard/analytics'
preLoaderRoute: typeof DashboardAnalyticsImport
parentRoute: typeof DashboardImport
}
'/dashboard/availabilities': {
id: '/dashboard/availabilities'
path: '/availabilities'
@ -118,6 +179,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DashboardAvailabilitiesImport
parentRoute: typeof DashboardImport
}
'/dashboard/device': {
id: '/dashboard/device'
path: '/device'
fullPath: '/dashboard/device'
preLoaderRoute: typeof DashboardDeviceImport
parentRoute: typeof DashboardImport
}
'/dashboard/disclaimer': {
id: '/dashboard/disclaimer'
path: '/disclaimer'
@ -132,6 +200,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DashboardFavoritesImport
parentRoute: typeof DashboardImport
}
'/dashboard/files': {
id: '/dashboard/files'
path: '/files'
fullPath: '/dashboard/files'
preLoaderRoute: typeof DashboardFilesImport
parentRoute: typeof DashboardImport
}
'/dashboard/help': {
id: '/dashboard/help'
path: '/help'
@ -139,6 +214,20 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DashboardHelpImport
parentRoute: typeof DashboardImport
}
'/dashboard/logs': {
id: '/dashboard/logs'
path: '/logs'
fullPath: '/dashboard/logs'
preLoaderRoute: typeof DashboardLogsImport
parentRoute: typeof DashboardImport
}
'/dashboard/nodes': {
id: '/dashboard/nodes'
path: '/nodes'
fullPath: '/dashboard/nodes'
preLoaderRoute: typeof DashboardNodesImport
parentRoute: typeof DashboardImport
}
'/dashboard/peers': {
id: '/dashboard/peers'
path: '/peers'
@ -167,6 +256,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DashboardSettingsImport
parentRoute: typeof DashboardImport
}
'/dashboard/wallet': {
id: '/dashboard/wallet'
path: '/wallet'
fullPath: '/dashboard/wallet'
preLoaderRoute: typeof DashboardWalletImport
parentRoute: typeof DashboardImport
}
'/dashboard/': {
id: '/dashboard/'
path: '/'
@ -181,27 +277,39 @@ declare module '@tanstack/react-router' {
interface DashboardRouteChildren {
DashboardAboutRoute: typeof DashboardAboutRoute
DashboardAnalyticsRoute: typeof DashboardAnalyticsRoute
DashboardAvailabilitiesRoute: typeof DashboardAvailabilitiesRoute
DashboardDeviceRoute: typeof DashboardDeviceRoute
DashboardDisclaimerRoute: typeof DashboardDisclaimerRoute
DashboardFavoritesRoute: typeof DashboardFavoritesRoute
DashboardFilesRoute: typeof DashboardFilesRoute
DashboardHelpRoute: typeof DashboardHelpRoute
DashboardLogsRoute: typeof DashboardLogsRoute
DashboardNodesRoute: typeof DashboardNodesRoute
DashboardPeersRoute: typeof DashboardPeersRoute
DashboardPurchasesRoute: typeof DashboardPurchasesRoute
DashboardRequestsRoute: typeof DashboardRequestsRoute
DashboardSettingsRoute: typeof DashboardSettingsRoute
DashboardWalletRoute: typeof DashboardWalletRoute
DashboardIndexRoute: typeof DashboardIndexRoute
}
const DashboardRouteChildren: DashboardRouteChildren = {
DashboardAboutRoute: DashboardAboutRoute,
DashboardAnalyticsRoute: DashboardAnalyticsRoute,
DashboardAvailabilitiesRoute: DashboardAvailabilitiesRoute,
DashboardDeviceRoute: DashboardDeviceRoute,
DashboardDisclaimerRoute: DashboardDisclaimerRoute,
DashboardFavoritesRoute: DashboardFavoritesRoute,
DashboardFilesRoute: DashboardFilesRoute,
DashboardHelpRoute: DashboardHelpRoute,
DashboardLogsRoute: DashboardLogsRoute,
DashboardNodesRoute: DashboardNodesRoute,
DashboardPeersRoute: DashboardPeersRoute,
DashboardPurchasesRoute: DashboardPurchasesRoute,
DashboardRequestsRoute: DashboardRequestsRoute,
DashboardSettingsRoute: DashboardSettingsRoute,
DashboardWalletRoute: DashboardWalletRoute,
DashboardIndexRoute: DashboardIndexRoute,
}
@ -213,28 +321,40 @@ export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/dashboard': typeof DashboardRouteWithChildren
'/dashboard/about': typeof DashboardAboutRoute
'/dashboard/analytics': typeof DashboardAnalyticsRoute
'/dashboard/availabilities': typeof DashboardAvailabilitiesRoute
'/dashboard/device': typeof DashboardDeviceRoute
'/dashboard/disclaimer': typeof DashboardDisclaimerRoute
'/dashboard/favorites': typeof DashboardFavoritesRoute
'/dashboard/files': typeof DashboardFilesRoute
'/dashboard/help': typeof DashboardHelpRoute
'/dashboard/logs': typeof DashboardLogsRoute
'/dashboard/nodes': typeof DashboardNodesRoute
'/dashboard/peers': typeof DashboardPeersRoute
'/dashboard/purchases': typeof DashboardPurchasesRoute
'/dashboard/requests': typeof DashboardRequestsRoute
'/dashboard/settings': typeof DashboardSettingsRoute
'/dashboard/wallet': typeof DashboardWalletRoute
'/dashboard/': typeof DashboardIndexRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/dashboard/about': typeof DashboardAboutRoute
'/dashboard/analytics': typeof DashboardAnalyticsRoute
'/dashboard/availabilities': typeof DashboardAvailabilitiesRoute
'/dashboard/device': typeof DashboardDeviceRoute
'/dashboard/disclaimer': typeof DashboardDisclaimerRoute
'/dashboard/favorites': typeof DashboardFavoritesRoute
'/dashboard/files': typeof DashboardFilesRoute
'/dashboard/help': typeof DashboardHelpRoute
'/dashboard/logs': typeof DashboardLogsRoute
'/dashboard/nodes': typeof DashboardNodesRoute
'/dashboard/peers': typeof DashboardPeersRoute
'/dashboard/purchases': typeof DashboardPurchasesRoute
'/dashboard/requests': typeof DashboardRequestsRoute
'/dashboard/settings': typeof DashboardSettingsRoute
'/dashboard/wallet': typeof DashboardWalletRoute
'/dashboard': typeof DashboardIndexRoute
}
@ -243,14 +363,20 @@ export interface FileRoutesById {
'/': typeof IndexRoute
'/dashboard': typeof DashboardRouteWithChildren
'/dashboard/about': typeof DashboardAboutRoute
'/dashboard/analytics': typeof DashboardAnalyticsRoute
'/dashboard/availabilities': typeof DashboardAvailabilitiesRoute
'/dashboard/device': typeof DashboardDeviceRoute
'/dashboard/disclaimer': typeof DashboardDisclaimerRoute
'/dashboard/favorites': typeof DashboardFavoritesRoute
'/dashboard/files': typeof DashboardFilesRoute
'/dashboard/help': typeof DashboardHelpRoute
'/dashboard/logs': typeof DashboardLogsRoute
'/dashboard/nodes': typeof DashboardNodesRoute
'/dashboard/peers': typeof DashboardPeersRoute
'/dashboard/purchases': typeof DashboardPurchasesRoute
'/dashboard/requests': typeof DashboardRequestsRoute
'/dashboard/settings': typeof DashboardSettingsRoute
'/dashboard/wallet': typeof DashboardWalletRoute
'/dashboard/': typeof DashboardIndexRoute
}
@ -260,41 +386,59 @@ export interface FileRouteTypes {
| '/'
| '/dashboard'
| '/dashboard/about'
| '/dashboard/analytics'
| '/dashboard/availabilities'
| '/dashboard/device'
| '/dashboard/disclaimer'
| '/dashboard/favorites'
| '/dashboard/files'
| '/dashboard/help'
| '/dashboard/logs'
| '/dashboard/nodes'
| '/dashboard/peers'
| '/dashboard/purchases'
| '/dashboard/requests'
| '/dashboard/settings'
| '/dashboard/wallet'
| '/dashboard/'
fileRoutesByTo: FileRoutesByTo
to:
| '/'
| '/dashboard/about'
| '/dashboard/analytics'
| '/dashboard/availabilities'
| '/dashboard/device'
| '/dashboard/disclaimer'
| '/dashboard/favorites'
| '/dashboard/files'
| '/dashboard/help'
| '/dashboard/logs'
| '/dashboard/nodes'
| '/dashboard/peers'
| '/dashboard/purchases'
| '/dashboard/requests'
| '/dashboard/settings'
| '/dashboard/wallet'
| '/dashboard'
id:
| '__root__'
| '/'
| '/dashboard'
| '/dashboard/about'
| '/dashboard/analytics'
| '/dashboard/availabilities'
| '/dashboard/device'
| '/dashboard/disclaimer'
| '/dashboard/favorites'
| '/dashboard/files'
| '/dashboard/help'
| '/dashboard/logs'
| '/dashboard/nodes'
| '/dashboard/peers'
| '/dashboard/purchases'
| '/dashboard/requests'
| '/dashboard/settings'
| '/dashboard/wallet'
| '/dashboard/'
fileRoutesById: FileRoutesById
}
@ -332,14 +476,20 @@ export const routeTree = rootRoute
"filePath": "dashboard.tsx",
"children": [
"/dashboard/about",
"/dashboard/analytics",
"/dashboard/availabilities",
"/dashboard/device",
"/dashboard/disclaimer",
"/dashboard/favorites",
"/dashboard/files",
"/dashboard/help",
"/dashboard/logs",
"/dashboard/nodes",
"/dashboard/peers",
"/dashboard/purchases",
"/dashboard/requests",
"/dashboard/settings",
"/dashboard/wallet",
"/dashboard/"
]
},
@ -347,10 +497,18 @@ export const routeTree = rootRoute
"filePath": "dashboard/about.tsx",
"parent": "/dashboard"
},
"/dashboard/analytics": {
"filePath": "dashboard/analytics.tsx",
"parent": "/dashboard"
},
"/dashboard/availabilities": {
"filePath": "dashboard/availabilities.tsx",
"parent": "/dashboard"
},
"/dashboard/device": {
"filePath": "dashboard/device.tsx",
"parent": "/dashboard"
},
"/dashboard/disclaimer": {
"filePath": "dashboard/disclaimer.tsx",
"parent": "/dashboard"
@ -359,10 +517,22 @@ export const routeTree = rootRoute
"filePath": "dashboard/favorites.tsx",
"parent": "/dashboard"
},
"/dashboard/files": {
"filePath": "dashboard/files.tsx",
"parent": "/dashboard"
},
"/dashboard/help": {
"filePath": "dashboard/help.tsx",
"parent": "/dashboard"
},
"/dashboard/logs": {
"filePath": "dashboard/logs.tsx",
"parent": "/dashboard"
},
"/dashboard/nodes": {
"filePath": "dashboard/nodes.tsx",
"parent": "/dashboard"
},
"/dashboard/peers": {
"filePath": "dashboard/peers.tsx",
"parent": "/dashboard"
@ -379,6 +549,10 @@ export const routeTree = rootRoute
"filePath": "dashboard/settings.tsx",
"parent": "/dashboard"
},
"/dashboard/wallet": {
"filePath": "dashboard/wallet.tsx",
"parent": "/dashboard"
},
"/dashboard/": {
"filePath": "dashboard/index.tsx",
"parent": "/dashboard"

View File

@ -1,22 +1,22 @@
import { createFileRoute, Link, Outlet } from "@tanstack/react-router";
import "./dashboard.css";
import {
MenuItem,
MenuItemComponentProps,
Page,
} from "@codex-storage/marketplace-ui-components";
import {
Home,
ShoppingBag,
Server,
Settings,
HelpCircle,
TriangleAlert,
Earth,
} from "lucide-react";
import { ICON_SIZE } from "../utils/constants";
import { NodeIndicator } from "../components/NodeIndicator/NodeIndicator";
import { HttpNetworkIndicator } from "../components/HttpNetworkIndicator/HttpNetworkIndicator";
import { Page } from "../components/Page/Page";
import { HomeIcon } from "../components/Menu/HomeIcon";
import { WalletIcon } from "../components/Menu/WalletIcon";
import { NodesIcon } from "../components/Menu/NodesIcon";
import { FilesIcon } from "../components/Menu/FilesIcon";
import { AnalyticsIcon } from "../components/Menu/AnalyticsIcon";
import { PurchaseIcon } from "../components/Menu/PurchaseIcon";
import { PeersIcon } from "../components/Menu/PeersIcon";
import { LogsIcon } from "../components/Menu/LogsIcon";
import { MenuItem, MenuItemComponentProps } from "../components/Menu/Menu";
import { HelpIcon } from "../components/Menu/HelpIcon";
import { DisclaimerIcon } from "../components/Menu/DisclaimerIcon";
import { SettingsIcon } from "../components/Menu/SettingsIcon";
import { HostIcon } from "../components/Menu/HostIcon";
import { DeviceIcon } from "../components/Menu/DeviceIcon";
const Layout = () => {
const Right = (
@ -28,11 +28,68 @@ const Layout = () => {
const items = [
{
type: "menu-item",
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard" activeOptions={{ exact: true }} {...p}>
<Home size={ICON_SIZE} />
Dashboard
<span className="menu-icon">
<HomeIcon />
</span>
<span className="menu-text">Dashboard</span>
</Link>
),
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/wallet" {...p}>
<span className="menu-icon">
<WalletIcon />
</span>
<span className="menu-text">Wallet</span>
</Link>
),
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/nodes" {...p}>
<span className="menu-icon">
<NodesIcon />
</span>
<span className="menu-text">Nodes</span>
</Link>
),
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/files" {...p}>
<span className="menu-icon">
<FilesIcon />
</span>
<span className="menu-text">Files</span>
</Link>
),
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/analytics" {...p}>
<span className="menu-icon">
<AnalyticsIcon />
</span>
<span className="menu-text">Analytics</span>
</Link>
),
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/device" {...p}>
<span className="menu-icon">
<DeviceIcon />
</span>
<span className="menu-text">Devices</span>
</Link>
),
},
@ -40,31 +97,24 @@ const Layout = () => {
type: "separator",
},
{
type: "menu-title",
title: "rent",
},
{
type: "menu-item",
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/purchases" {...p}>
<ShoppingBag size={ICON_SIZE} />
Purchases
<span className="menu-icon">
<PurchaseIcon />
</span>
<span className="menu-text">Purchases</span>
</Link>
),
},
{
type: "separator",
},
{
type: "menu-title",
title: "host",
},
{
type: "menu-item",
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/availabilities" {...p}>
<Server size={ICON_SIZE} />
Sales
<span className="menu-icon">
<HostIcon />
</span>
<span className="menu-text">Host</span>
</Link>
),
},
@ -72,40 +122,66 @@ const Layout = () => {
type: "separator",
},
{
type: "menu-item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/help" {...p}>
<HelpCircle size={"1.25rem"} /> Help
</Link>
),
},
{
type: "menu-item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/settings" {...p}>
<Settings size={ICON_SIZE} />
Settings
</Link>
),
},
{
type: "menu-item",
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/peers" {...p}>
<Earth size={ICON_SIZE} />
Peers
<span className="menu-icon">
<PeersIcon />
</span>
<span className="menu-text">Peers</span>
</Link>
),
},
{
type: "menu-item",
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/disclaimer" {...p}>
<TriangleAlert size={ICON_SIZE} />
Disclaimer
<Link to="/dashboard/logs" {...p}>
<span className="menu-icon">
<LogsIcon />
</span>
<span className="menu-text">Log</span>
</Link>
),
},
{
type: "space",
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/settings" {...p}>
<span className="menu-icon">
<SettingsIcon />
</span>
<span className="menu-text">Settings</span>
</Link>
),
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/help" {...p}>
<span className="menu-icon">
<HelpIcon />
</span>
<span className="menu-text">Help</span>
</Link>
),
},
{
type: "item",
Component: (p: MenuItemComponentProps) => (
<Link to="/dashboard/disclaimer" {...p}>
<span className="menu-icon">
<DisclaimerIcon />
</span>
<span className="menu-text">Disclaimer</span>
</Link>
),
},
{
type: "empty",
},
] satisfies MenuItem[];
return (

View File

@ -0,0 +1,5 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/dashboard/analytics")({
component: () => <div>Hello /dashboard/analytics!</div>,
});

View File

@ -0,0 +1,5 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/dashboard/device")({
component: () => <div>Hello /dashboard/device!</div>,
});

View File

@ -0,0 +1,5 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/dashboard/files")({
component: () => <div>Hello /dashboard/files!</div>,
});

View File

@ -0,0 +1,5 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/dashboard/logs")({
component: () => <div>Hello /dashboard/logs!</div>,
});

View File

@ -0,0 +1,5 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/dashboard/nodes')({
component: () => <div>Hello /nodes!</div>,
})

View File

@ -0,0 +1,5 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/dashboard/wallet")({
component: () => <div>Hello /dashboard/wallet!</div>,
});