Skip to content

Commit

Permalink
Layout mostly done
Browse files Browse the repository at this point in the history
  • Loading branch information
quietbits committed Feb 13, 2024
1 parent d8f9bb0 commit b897cb9
Show file tree
Hide file tree
Showing 21 changed files with 541 additions and 36 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"git-info": "rm -rf src/generated/ && mkdir src/generated/ && echo export default \"{\\\"commitHash\\\": \\\"$(git rev-parse --short HEAD)\\\", \\\"version\\\": \\\"$(git describe --tags --always)\\\"};\" > src/generated/gitInfo.ts"
},
"dependencies": {
"@stellar/design-system": "^1.1.2",
"@stellar/design-system": "^2.0.0-beta.1",
"next": "14.0.4",
"react": "^18",
"react-dom": "^18"
Expand Down
5 changes: 5 additions & 0 deletions src/app/(sidebar)/account/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"use client";

export default function CreateAccount() {
return <div>Create Account</div>;
}
5 changes: 5 additions & 0 deletions src/app/(sidebar)/account/fund/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"use client";

export default function FundAccount() {
return <div>Fund Account</div>;
}
5 changes: 5 additions & 0 deletions src/app/(sidebar)/account/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"use client";

export default function Account() {
return <div>Account content</div>;
}
38 changes: 38 additions & 0 deletions src/app/(sidebar)/account/template.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";

import { Icon } from "@stellar/design-system";
import { LayoutSidebarContent } from "@/components/LayoutSidebarContent";
import { Routes } from "@/constants/routes";

export default function AccountTemplate({
children,
}: {
children: React.ReactNode;
}) {
return (
<LayoutSidebarContent
sidebar={{
navItems: [
{
route: Routes.CREATE_ACCOUNT,
label: "Create Account",
},
{
route: Routes.FUND_ACCOUNT,
label: "Fund Account",
},
{
route: Routes.CREATE_MUXED_ACCOUNT,
label: "Create Muxed Account",
},
{
route: Routes.PARSE_MUXED_ACCOUNT,
label: "Parse Muxed Account",
},
],
}}
>
{children}
</LayoutSidebarContent>
);
}
9 changes: 9 additions & 0 deletions src/app/(sidebar)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { LayoutSidebar } from "@/components/LayoutSidebar";

export default function LayoutWithSidebar({
children,
}: {
children: React.ReactNode;
}) {
return <LayoutSidebar>{children}</LayoutSidebar>;
}
1 change: 0 additions & 1 deletion src/app/globals.scss

This file was deleted.

8 changes: 4 additions & 4 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Metadata } from "next";

import { MainLayout } from "./ui/MainLayout";
import { LayoutMain } from "@/components/LayoutMain";

import "@stellar/design-system/build/styles.min.css";
import "./globals.scss";
import "@/styles/globals.scss";

export const metadata: Metadata = {
title: "Laboratory - Stellar",
Expand All @@ -18,8 +18,8 @@ export default function RootLayout({
return (
<html lang="en">
<body>
<div id="root">
<MainLayout>{children}</MainLayout>
<div id="root" className="LabLayout">
<LayoutMain>{children}</LayoutMain>
</div>
</body>
</html>
Expand Down
15 changes: 15 additions & 0 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"use client";

import Link from "next/link";

import { Routes } from "@/constants/routes";

export default function NotFound() {
return (
<div>
<h2>Not Found</h2>
<p>Could not find requested resource</p>
<Link href={Routes.ROOT}>Return Home</Link>
</div>
);
}
12 changes: 8 additions & 4 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"use client";

import { Layout } from "@stellar/design-system";

export default function Home() {
return <Layout.Inset>Page</Layout.Inset>;
export default function Introduction() {
return (
<div className="LabLayout__container">
<div className="LabLayout__content">
<div>Introduction</div>
</div>
</div>
);
}
18 changes: 0 additions & 18 deletions src/app/ui/MainLayout.tsx

This file was deleted.

31 changes: 31 additions & 0 deletions src/components/LayoutMain.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";

import { ReactNode } from "react";
import Link from "next/link";

import { ProjectLogo, ThemeSwitch } from "@stellar/design-system";

import { MainNav } from "@/components/MainNav";

export const LayoutMain = ({ children }: { children: ReactNode }) => {
return (
<>
<div className="LabLayout__header">
<header className="LabLayout__header__main">
<ProjectLogo
title="Laboratory"
link="/"
customAnchor={<Link href="/" />}
/>

<div className="LabLayout__header__settings">
<ThemeSwitch storageKeyId="stellarTheme:Laboratory" />
</div>
</header>
<MainNav />
</div>

{children}
</>
);
};
7 changes: 7 additions & 0 deletions src/components/LayoutSidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"use client";

import { ReactNode } from "react";

export const LayoutSidebar = ({ children }: { children: ReactNode }) => {
return <div className="LabLayout__withSidebar">{children}</div>;
};
77 changes: 77 additions & 0 deletions src/components/LayoutSidebarContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"use client";

import { ReactNode } from "react";
import { usePathname } from "next/navigation";
import NextLink from "next/link";
import { Routes } from "@/constants/routes";
import { Icon } from "@stellar/design-system";

export type SidebarLink = {
route: Routes | string;
label: string;
icon?: ReactNode;
nestedItems?: SidebarLink[];
};

export type Sidebar = {
navItems: SidebarLink[];
instruction?: string;
bottomItems?: SidebarLink[];
};

export const LayoutSidebarContent = ({
children,
sidebar,
}: {
children: ReactNode;
sidebar: Sidebar;
}) => {
const pathname = usePathname();

const Link = ({ item }: { item: SidebarLink }) => (
<NextLink
href={item.route}
className={`SidebarLink ${
pathname === item.route ? "SidebarLink--active" : ""
}`}
>
{item.icon ?? null} {item.label}
</NextLink>
);

return (
<>
<div className="LabLayout__sidebar">
<div className="LabLayout__sidebar--top">
{/* TODO: add instruction */}
{/* TODO: render nested items */}

{sidebar.navItems.map((item) => (
<Link key={item.route} item={item} />
))}
</div>
<div
className={`LabLayout__sidebar--bottom ${
sidebar.bottomItems?.length
? "LabLayout__sidebar--bottom--border"
: ""
}`}
>
<div className="LabLayout__sidebar__wrapper">
{sidebar.bottomItems?.map((bi) => (
<Link key={bi.route} item={bi} />
))}
</div>
<div className="LabLayout__sidebar__wrapper">
<NextLink href="https://stellar.org" className="SidebarLink">
<Icon.MessageTextSquare02 /> Got product feedback?
</NextLink>
</div>
</div>
</div>
<div className="LabLayout__container">
<div className="LabLayout__content">{children}</div>
</div>
</>
);
};
78 changes: 78 additions & 0 deletions src/components/MainNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import NextLink from "next/link";
import { usePathname } from "next/navigation";

import { Routes } from "@/constants/routes";

type NavLink = {
href: Routes | string;
label: string;
};

const primaryNavLinks: NavLink[] = [
{
href: Routes.ROOT,
label: "Introduction",
},
{
href: Routes.CREATE_ACCOUNT,
label: "Account",
},
{
href: Routes.EXPLORE_ENDPOINTS,
label: "Explore Endpoints",
},
];

const secondaryNavLinks = [
{
href: "https://developers.stellar.org/docs",
label: "View Documentation",
},
];

export const MainNav = () => {
const pathname = usePathname();

const externalLinkProps = (href: string) => {
const isExternalLink = href?.startsWith("http") || href?.startsWith("//");

return isExternalLink
? { rel: "noreferrer noopener", target: "_blank" }
: {};
};

const isActiveRoute = (link: string) => {
if (link.startsWith("http")) {
return false;
}

return pathname.split("/")[1] === link.split("/")[1];
};

const NavItem = ({ link }: { link: NavLink }) => (
<NextLink
href={link.href}
className={`NavLink ${isActiveRoute(link.href) ? "NavLink--active" : ""}`}
{...externalLinkProps(link.href)}
>
{link.label}
</NextLink>
);

return (
<nav className="LabLayout__header__nav">
{/* Primary nav links */}
<div className="LabLayout__header__nav--primary">
{primaryNavLinks.map((l) => (
<NavItem key={l.href} link={l} />
))}
</div>
{/* Secondary nav links */}
<div className="LabLayout__header__nav--secondary">
{secondaryNavLinks.map((sl) => (
<NavItem key={sl.href} link={sl} />
))}
</div>
</nav>
);
};
11 changes: 11 additions & 0 deletions src/components/NavLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import NextLink from "next/link";
import { Props as LinkProps, Link } from "@stellar/design-system";

/** Use `NavLink` instead of `Link` from Stellar Design System to support client-side routing. `NavLink` uses `Link` from `next/link` internally. */
export const NavLink = (props: LinkProps) => {
return (
<Link {...props} customAnchor={<NextLink href={props.href || ""} />}>
{props.children}
</Link>
);
};
10 changes: 10 additions & 0 deletions src/constants/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export enum Routes {
ROOT = "/",
// Account
CREATE_ACCOUNT = "/account/create",
FUND_ACCOUNT = "/account/fund",
CREATE_MUXED_ACCOUNT = "/account/muxed-create",
PARSE_MUXED_ACCOUNT = "/account/muxed-parse",
// Explore Endpoints
EXPLORE_ENDPOINTS = "/explore-endpoints",
}
Loading

0 comments on commit b897cb9

Please sign in to comment.