diff --git a/package-lock.json b/package-lock.json index dee7ce7..f07ccd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.7", "license": "MIT", "dependencies": { - "@codex-storage/marketplace-ui-components": "^0.0.26", + "@codex-storage/marketplace-ui-components": "^0.0.27", "@codex-storage/sdk-js": "^0.0.12", "@sentry/browser": "^8.32.0", "@sentry/react": "^8.31.0", @@ -374,9 +374,9 @@ "dev": true }, "node_modules/@codex-storage/marketplace-ui-components": { - "version": "0.0.26", - "resolved": "https://registry.npmjs.org/@codex-storage/marketplace-ui-components/-/marketplace-ui-components-0.0.26.tgz", - "integrity": "sha512-x8niBv1HRJU6VnKJ5+tv3+yYMxOj0tnMdNaPGzHVXMTHpj5WeHRcqUR1UhxxxnIlnsOjhmjX2tVUYPxpAz+OEw==", + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/@codex-storage/marketplace-ui-components/-/marketplace-ui-components-0.0.27.tgz", + "integrity": "sha512-jCNUFeHNUptKSupSCQriwTXjK0zC8Yi7kcVWI20p9GtfNKPMRykhrpqGgQ6AdMMB9ZAliY5m+PH9ie3J/PWicw==", "dependencies": { "lucide-react": "^0.453.0" }, @@ -384,7 +384,7 @@ "node": ">=18" }, "peerDependencies": { - "@codex-storage/sdk-js": ">=0.0.7", + "@codex-storage/sdk-js": ">=0.0.12", "react": "^18.3.1", "react-dom": "^18.3.1" } diff --git a/package.json b/package.json index ee72e3e..27fc147 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "React" ], "dependencies": { - "@codex-storage/marketplace-ui-components": "^0.0.26", + "@codex-storage/marketplace-ui-components": "^0.0.27", "@codex-storage/sdk-js": "^0.0.12", "@sentry/browser": "^8.32.0", "@sentry/react": "^8.31.0", diff --git a/public/img/avatar.png b/public/img/avatar.png new file mode 100644 index 0000000..1b14108 Binary files /dev/null and b/public/img/avatar.png differ diff --git a/public/img/avatar.webp b/public/img/avatar.webp new file mode 100644 index 0000000..2d800fd Binary files /dev/null and b/public/img/avatar.webp differ diff --git a/public/img/avatar@1.5x.png b/public/img/avatar@1.5x.png new file mode 100644 index 0000000..063a63e Binary files /dev/null and b/public/img/avatar@1.5x.png differ diff --git a/public/img/avatar@1.5x.webp b/public/img/avatar@1.5x.webp new file mode 100644 index 0000000..6ce7d15 Binary files /dev/null and b/public/img/avatar@1.5x.webp differ diff --git a/public/img/avatar@2x.png b/public/img/avatar@2x.png new file mode 100644 index 0000000..3e103b3 Binary files /dev/null and b/public/img/avatar@2x.png differ diff --git a/public/img/avatar@2x.webp b/public/img/avatar@2x.webp new file mode 100644 index 0000000..453ee11 Binary files /dev/null and b/public/img/avatar@2x.webp differ diff --git a/public/img/avatar@3x.png b/public/img/avatar@3x.png new file mode 100644 index 0000000..57b91d4 Binary files /dev/null and b/public/img/avatar@3x.png differ diff --git a/public/img/avatar@3x.webp b/public/img/avatar@3x.webp new file mode 100644 index 0000000..f6826e7 Binary files /dev/null and b/public/img/avatar@3x.webp differ diff --git a/public/img/avatar@4x.png b/public/img/avatar@4x.png new file mode 100644 index 0000000..8a0d5a2 Binary files /dev/null and b/public/img/avatar@4x.png differ diff --git a/public/img/avatar@4x.webp b/public/img/avatar@4x.webp new file mode 100644 index 0000000..610e555 Binary files /dev/null and b/public/img/avatar@4x.webp differ diff --git a/src/components/AlphaText/AlphaText.tsx b/src/components/AlphaText/AlphaText.tsx index 6a679f7..94c33b7 100644 --- a/src/components/AlphaText/AlphaText.tsx +++ b/src/components/AlphaText/AlphaText.tsx @@ -1,35 +1,40 @@ -export function AlphaText() { +type Props = { + variant: "default" | "failure"; + className?: string; + width?: number; +}; + +export function AlphaText({ variant, className = "", width = 72 }: Props) { + const attr = + variant === "default" + ? { opacity: "0.6", fill: "white" } + : { fill: "#CC6C6C" }; return ( ); diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx index f5c8c1c..2abbac9 100644 --- a/src/components/AppBar/AppBar.tsx +++ b/src/components/AppBar/AppBar.tsx @@ -1,6 +1,7 @@ -import { Menu } from "lucide-react"; import "./appBar.css"; -import { ReactNode } from "react"; +import { DashboardIcon } from "../DashboardIcon/DashboardIcon"; +import { NodeIndicator } from "../NodeIndicator/NodeIndicator"; +import { HttpNetworkIndicator } from "../HttpNetworkIndicator/HttpNetworkIndicator"; type Props = { /** @@ -8,23 +9,31 @@ type Props = { * menu button. */ onExpand: () => void; - - /** - * React node to add to the right part of the application bar - */ - Right: ReactNode; }; -export function AppBar({ onExpand, Right }: Props) { +export function AppBar(props: Props) { + console.info(props); return (
- + {/* - - Home + */} + +
+ +
+
+
Dashboard
+
+ Get Overview of your Codex Vault +
+
+
+
+ +
-
{Right}
); } diff --git a/src/components/AppBar/appBar.css b/src/components/AppBar/appBar.css index f2be905..90ad824 100644 --- a/src/components/AppBar/appBar.css +++ b/src/components/AppBar/appBar.css @@ -1,10 +1,13 @@ .appBar { - height: 40px; + height: 80px; justify-content: space-between; border-bottom: 1px solid var(--codex-border-color); view-transition-name: main-header; display: flex; - padding: 0.75rem 1.5rem; + padding: 20px 40px 20px 40px; + border-bottom: 1px solid #2b303b; + box-sizing: border-box; + background-color: #1c1c1c; } .appBar-burger { @@ -18,11 +21,36 @@ .appBar-right { display: flex; align-items: center; + gap: 16px; } -.appBar-left, -.appBar-right { - gap: 0.75rem; +.appBar-icon { + background: #141414; + height: 48px; + width: 48px; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid #353639; + border-radius: 50%; +} + +.appBar-title { + font-family: Inter; + font-size: 18px; + font-weight: 500; + line-height: 24px; + letter-spacing: -0.015em; + color: white; +} + +.appBar-subtitle { + font-family: Inter; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: -0.006em; + color: #969696cc; } @media (min-width: 1000px) { diff --git a/src/components/DashboardIcon/DashboardIcon.tsx b/src/components/DashboardIcon/DashboardIcon.tsx new file mode 100644 index 0000000..b64ed92 --- /dev/null +++ b/src/components/DashboardIcon/DashboardIcon.tsx @@ -0,0 +1,15 @@ +export function DashboardIcon() { + return ( + + + + ); +} diff --git a/src/components/HttpNetworkIndicator/HttpNetworkIndicator.css b/src/components/HttpNetworkIndicator/HttpNetworkIndicator.css new file mode 100644 index 0000000..1125719 --- /dev/null +++ b/src/components/HttpNetworkIndicator/HttpNetworkIndicator.css @@ -0,0 +1,24 @@ +.network-indicator { + display: flex; + align-items: center; + gap: 16px; +} + +.network-indicator-icon { + background-color: #141414; + border-radius: var(--codex-border-radius); + height: 40px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; +} + +.network-indicator-text { + font-family: Inter; + font-size: 14px; + font-weight: 500; + line-height: 20px; + letter-spacing: -0.006em; + color: #8d8d8d; +} diff --git a/src/components/HttpNetworkIndicator/HttpNetworkIndicator.tsx b/src/components/HttpNetworkIndicator/HttpNetworkIndicator.tsx index f06a392..d0c98df 100644 --- a/src/components/HttpNetworkIndicator/HttpNetworkIndicator.tsx +++ b/src/components/HttpNetworkIndicator/HttpNetworkIndicator.tsx @@ -1,10 +1,16 @@ -import { NetworkIndicator } from "@codex-storage/marketplace-ui-components"; import { useNetwork } from "../../network/useNetwork"; +import { NetworkFlashIcon } from "../NetworkFlashIcon/NetworkFlashIcon"; +import "./HttpNetworkIndicator.css"; export function HttpNetworkIndicator() { const online = useNetwork(); - const text = online ? "Online" : "Offline"; - - return ; + return ( +
+
+ +
+ Network +
+ ); } diff --git a/src/components/Menu/NodesIcon.tsx b/src/components/Menu/NodesIcon.tsx index 37e02af..241836a 100644 --- a/src/components/Menu/NodesIcon.tsx +++ b/src/components/Menu/NodesIcon.tsx @@ -1,4 +1,18 @@ -export function NodesIcon() { +type Props = { + variant: "default" | "success" | "failure"; +}; + +export function NodesIcon({ variant }: Props) { + let color = "currentColor"; + + if (variant === "success") { + color = "#3EE089"; + } + + if (variant === "failure") { + color = "var(--codex-color-error-hexa)"; + } + return ( ); diff --git a/src/components/NetworkFlashIcon/NetworkFlashIcon.tsx b/src/components/NetworkFlashIcon/NetworkFlashIcon.tsx new file mode 100644 index 0000000..2aa98ed --- /dev/null +++ b/src/components/NetworkFlashIcon/NetworkFlashIcon.tsx @@ -0,0 +1,18 @@ +type Props = { + online: boolean; +}; + +export function NetworkFlashIcon({ online }: Props) { + const color = online ? "#3EE089" : "var(--codex-color-error-hexa)"; + + return ( + + + + ); +} diff --git a/src/components/NetworkIcon/NetworkIcon.tsx b/src/components/NetworkIcon/NetworkIcon.tsx index 4b62669..e1cf31b 100644 --- a/src/components/NetworkIcon/NetworkIcon.tsx +++ b/src/components/NetworkIcon/NetworkIcon.tsx @@ -3,9 +3,7 @@ type Props = { }; export function NetworkIcon({ active }: Props) { - const stroke = active - ? "var(--codex-color-primary)" - : "rgb(var(--codex-color-error))"; + const stroke = active ? "#3EE089" : "rgb(var(--codex-color-error))"; return ( { @@ -23,8 +17,12 @@ export function NodeIndicator() { return ( <> - - +
+
+ +
+ Node +
); } diff --git a/src/components/OnBoarding/AlphaIcon.tsx b/src/components/OnBoarding/AlphaIcon.tsx index 3675507..7970537 100644 --- a/src/components/OnBoarding/AlphaIcon.tsx +++ b/src/components/OnBoarding/AlphaIcon.tsx @@ -1,14 +1,16 @@ type Props = { variant: "primary" | "error"; + className?: string; }; -export function AlphaIcon({ variant }: Props) { +export function AlphaIcon({ variant, className = "" }: Props) { const color = variant === "primary" ? "var(--codex-color-primary)" : "var(--codex-color-error-hexa)"; return (
- +

- +

diff --git a/src/components/Page/Page.tsx b/src/components/Page/Page.tsx index 95d5578..94a3fd4 100644 --- a/src/components/Page/Page.tsx +++ b/src/components/Page/Page.tsx @@ -6,14 +6,12 @@ import "./page.css"; type Props = { children: ReactNode; - Right: ReactNode; - items: MenuItem[]; version?: string; }; -export function Page({ children, Right, items, version = "" }: Props) { +export function Page({ children, items, version = "" }: Props) { const [open, setOpen] = useState(false); const onClose = () => setOpen(false); @@ -29,7 +27,7 @@ export function Page({ children, Right, items, version = "" }: Props) { version={version}>

- + {children}
diff --git a/src/routes/dashboard.css b/src/routes/dashboard.css index 98eea6f..cd5ea62 100644 --- a/src/routes/dashboard.css +++ b/src/routes/dashboard.css @@ -22,6 +22,36 @@ margin-bottom: 0; } +.dashboard-welcome-versions { + display: flex; + gap: 32px; +} + +.dashboard-welcome-versionContainer { + width: 50px; + text-align: right; +} + +.dashboard-welcome-versionTitle { + font-family: Inter; + font-size: 16px; + font-weight: 500; + line-height: 24px; + letter-spacing: -0.011em; + color: #99a0ae; +} + +.dashboard-welcome-versionValue { + font-family: Inter; + font-size: 10px; + font-weight: 400; + line-height: 12.1px; + letter-spacing: 0.01em; + color: white; + text-transform: uppercase; + white-space: nowrap; +} + @media (min-width: 1000px) { .dashboard { grid-template-columns: repeat(2, minmax(0, 1fr)); diff --git a/src/routes/dashboard.tsx b/src/routes/dashboard.tsx index dafd139..aa0e0ed 100644 --- a/src/routes/dashboard.tsx +++ b/src/routes/dashboard.tsx @@ -1,7 +1,5 @@ import { createFileRoute, Link, Outlet } from "@tanstack/react-router"; import "./dashboard.css"; -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"; @@ -19,13 +17,6 @@ import { HostIcon } from "../components/Menu/HostIcon"; import { DeviceIcon } from "../components/Menu/DeviceIcon"; const Layout = () => { - const Right = ( - <> - - - - ); - const items = [ { type: "item", @@ -70,7 +61,7 @@ const Layout = () => { aria-disabled={true} data-title="Coming soon"> - + Nodes @@ -202,7 +193,6 @@ const Layout = () => { } items={items} - Right={Right} version={import.meta.env.PACKAGE_VERSION} /> ); diff --git a/src/routes/dashboard/index.css b/src/routes/dashboard/index.css new file mode 100644 index 0000000..ab107e6 --- /dev/null +++ b/src/routes/dashboard/index.css @@ -0,0 +1,34 @@ +.dashboard-welcomeContainer { + padding: 24px 48px; + display: flex; + justify-content: space-between; +} + +.dashboard-welcome-avatarContainer { + display: flex; + gap: 16px; +} + +.dashboard-welcome-avatarTitle { + font-family: Inter; + font-size: 12px; + font-weight: 700; + line-height: 14.52px; + letter-spacing: 0.01em; + color: #969696cc; + text-transform: uppercase; +} + +.dashboard-welcome-avatarSubtitle { + font-family: Inter; + font-size: 32px; + font-weight: 400; + line-height: 38.73px; + letter-spacing: 0.01em; + color: white; +} + +.dashboard-welcome-alpha { + position: relative; + top: 6px; +} diff --git a/src/routes/dashboard/index.tsx b/src/routes/dashboard/index.tsx index c644acc..52c5d74 100644 --- a/src/routes/dashboard/index.tsx +++ b/src/routes/dashboard/index.tsx @@ -8,20 +8,83 @@ import { ErrorBoundary } from "@sentry/react"; import { useQueryClient } from "@tanstack/react-query"; import { Download } from "../../components/Download/Download.tsx"; import { ManifestFetch } from "../../components/ManifestFetch/ManifestFetch.tsx"; +import { OnBoardingUtils } from "../../utils/onboarding.ts"; +import "./index.css"; +import { AlphaIcon } from "../../components/OnBoarding/AlphaIcon.tsx"; +import { AlphaText } from "../../components/AlphaText/AlphaText.tsx"; +import { useDebug } from "../../hooks/useDebug.ts"; export const Route = createFileRoute("/dashboard/")({ - component: About, + component: Dashboard, }); -function About() { +const throwOnError = false; + +function Dashboard() { const queryClient = useQueryClient(); + const debug = useDebug(throwOnError); const onSuccess = () => { queryClient.invalidateQueries({ queryKey: ["cids"] }); }; + const username = OnBoardingUtils.getDisplayName(); + + const parts = debug.data?.codex.version.split("\n") || [""]; + const version = parts[parts.length - 1]; + return ( <> +
+
+ + + + Avatar + +
+
Welcome back,
+
{username}
+
+
+
+ +
+

Client

+

VER. {version}

+
+
+

Vault

+

+ VER. {import.meta.env.PACKAGE_VERSION} +

+ +
+
+
setIsStepValid(valid);