mirror of
https://github.com/logos-storage/logos-storage-marketplace-ui.git
synced 2026-01-04 06:23:08 +00:00
Menu implementation
This commit is contained in:
parent
7ec8262953
commit
6b9c91f167
30
src/components/AppBar/AppBar.tsx
Normal file
30
src/components/AppBar/AppBar.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
32
src/components/AppBar/appBar.css
Normal file
32
src/components/AppBar/appBar.css
Normal 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;
|
||||
}
|
||||
}
|
||||
40
src/components/Logo/Logo.tsx
Normal file
40
src/components/Logo/Logo.tsx
Normal 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
15
src/components/Menu/AnalyticsIcon.tsx
Normal file
15
src/components/Menu/AnalyticsIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/DeviceIcon.tsx
Normal file
15
src/components/Menu/DeviceIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/DisclaimerIcon.tsx
Normal file
15
src/components/Menu/DisclaimerIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
27
src/components/Menu/ExpandIcon.tsx
Normal file
27
src/components/Menu/ExpandIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/FilesIcon.tsx
Normal file
15
src/components/Menu/FilesIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/HelpIcon.tsx
Normal file
15
src/components/Menu/HelpIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/HomeIcon.tsx
Normal file
15
src/components/Menu/HomeIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/HostIcon.tsx
Normal file
15
src/components/Menu/HostIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/LogsIcon.tsx
Normal file
15
src/components/Menu/LogsIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
114
src/components/Menu/Menu.tsx
Normal file
114
src/components/Menu/Menu.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/NodesIcon.tsx
Normal file
15
src/components/Menu/NodesIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/PeersIcon.tsx
Normal file
15
src/components/Menu/PeersIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
22
src/components/Menu/PurchaseIcon.tsx
Normal file
22
src/components/Menu/PurchaseIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/SettingsIcon.tsx
Normal file
15
src/components/Menu/SettingsIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
15
src/components/Menu/WalletIcon.tsx
Normal file
15
src/components/Menu/WalletIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
225
src/components/Menu/menu.css
Normal file
225
src/components/Menu/menu.css
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,6 @@ import "./OnBoardingStepThree.css";
|
||||
import { usePortForwarding } from "../../hooks/usePortForwarding";
|
||||
import { useCodexConnection } from "../../hooks/useCodexConnection";
|
||||
import {
|
||||
Button,
|
||||
ButtonIcon,
|
||||
Input,
|
||||
SimpleText,
|
||||
|
||||
37
src/components/Page/Page.tsx
Normal file
37
src/components/Page/Page.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
8
src/components/Page/page.css
Normal file
8
src/components/Page/page.css
Normal file
@ -0,0 +1,8 @@
|
||||
.page {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.page-main {
|
||||
flex: 1;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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 (
|
||||
|
||||
5
src/routes/dashboard/analytics.tsx
Normal file
5
src/routes/dashboard/analytics.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/dashboard/analytics")({
|
||||
component: () => <div>Hello /dashboard/analytics!</div>,
|
||||
});
|
||||
5
src/routes/dashboard/device.tsx
Normal file
5
src/routes/dashboard/device.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/dashboard/device")({
|
||||
component: () => <div>Hello /dashboard/device!</div>,
|
||||
});
|
||||
5
src/routes/dashboard/files.tsx
Normal file
5
src/routes/dashboard/files.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/dashboard/files")({
|
||||
component: () => <div>Hello /dashboard/files!</div>,
|
||||
});
|
||||
5
src/routes/dashboard/logs.tsx
Normal file
5
src/routes/dashboard/logs.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/dashboard/logs")({
|
||||
component: () => <div>Hello /dashboard/logs!</div>,
|
||||
});
|
||||
5
src/routes/dashboard/nodes.tsx
Normal file
5
src/routes/dashboard/nodes.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/dashboard/nodes')({
|
||||
component: () => <div>Hello /nodes!</div>,
|
||||
})
|
||||
5
src/routes/dashboard/wallet.tsx
Normal file
5
src/routes/dashboard/wallet.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
export const Route = createFileRoute("/dashboard/wallet")({
|
||||
component: () => <div>Hello /dashboard/wallet!</div>,
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user