Skip to content

Commit

Permalink
Refactor navigation (#285)
Browse files Browse the repository at this point in the history
* refactor: navigation

* feat: add cli page

* fix: minor fixes
  • Loading branch information
esemyonov authored Dec 18, 2023
1 parent df618fe commit b5a530c
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 119 deletions.
26 changes: 25 additions & 1 deletion sidebar.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
"label": "Introduction",
"href": "/",
"type": "category",
"items": [
"articles/what-is-zuplo",
"articles/who-uses-and-why",
Expand All @@ -10,6 +11,7 @@
},
{
"label": "Getting Started",
"type": "category",
"items": [
"articles/step-1-setup-basic-gateway",
"articles/step-2-add-api-key-auth",
Expand All @@ -33,6 +35,7 @@
// },
{
"label": "Getting to Production",
"type": "category",
"items": [
"articles/environments",
"articles/github-source-control",
Expand All @@ -47,6 +50,7 @@
},
{
"label": "API Keys",
"type": "category",
"items": [
"articles/api-key-management",
"articles/api-key-authentication",
Expand All @@ -65,9 +69,11 @@
// },
{
"label": "How to Guides",
"type": "category",
"items": [
{
"label": "Local Development",
"type": "sub_category",
"items": [
"articles/local-development",
"articles/configure-ide-for-local-development"
Expand All @@ -93,9 +99,11 @@
{
"label": "Policies",
"href": "/policies",
"type": "category",
"items": [
{
"label": "Authentication",
"type": "sub_category",
"items": [
"policies/api-key-inbound",
"policies/auth0-jwt-auth-inbound",
Expand All @@ -113,6 +121,7 @@
},
{
"label": "Security & Validation",
"type": "sub_category",
"items": [
"policies/rate-limit-inbound",
"policies/audit-log-inbound",
Expand All @@ -123,6 +132,7 @@
},
{
"label": "Metrics, Billing & Quotas",
"type": "sub_category",
"items": [
"policies/quota-inbound",
"policies/moesif-inbound",
Expand All @@ -132,6 +142,7 @@
},
{
"label": "Testing",
"type": "sub_category",
"items": [
"policies/ab-test-inbound",
"policies/mock-api-inbound",
Expand All @@ -140,6 +151,7 @@
},
{
"label": "Request Filtering",
"type": "sub_category",
"items": [
"policies/acl-policy-inbound",
"policies/geo-filter-inbound",
Expand All @@ -149,6 +161,7 @@
},
{
"label": "Request Modification",
"type": "sub_category",
"items": [
"policies/transform-body-inbound",
"policies/remove-headers-inbound",
Expand All @@ -163,6 +176,7 @@
},
{
"label": "Response Modification",
"type": "sub_category",
"items": [
"policies/transform-body-outbound",
"policies/remove-headers-outbound",
Expand All @@ -173,6 +187,7 @@
},
{
"label": "Upstream Authentication",
"type": "sub_category",
"items": [
"policies/upstream-azure-ad-service-auth-inbound",
"policies/upstream-gcp-service-auth-inbound",
Expand All @@ -183,6 +198,7 @@
},
{
"label": "Other",
"type": "sub_category",
"items": [
"policies/composite-inbound",
"policies/caching-inbound",
Expand All @@ -194,10 +210,12 @@
},
{
"label": "Reference",
"type": "category",
"items": [
{
"label": "Handlers",
"href": "/handlers",
"type": "sub_category",
"items": [
"handlers/url-forward",
"handlers/url-rewrite",
Expand All @@ -210,6 +228,7 @@
},
{
"label": "Developer Portal",
"type": "sub_category",
"items": [
"articles/developer-portal",
"articles/dev-portal-setup",
Expand All @@ -225,6 +244,7 @@
},
{
"label": "Programming API",
"type": "sub_category",
"items": [
"articles/zuplo-request",
"articles/environment-variables",
Expand All @@ -251,6 +271,7 @@
{
"label": "Zuplo CLI",
"href": "/cli",
"type": "sub_category",
"items": [
"cli/installation",
"cli/analytics",
Expand All @@ -266,15 +287,18 @@
},
{
"label": "Product Info",
"item": [
"type": "category",
"items": [
"articles/support",
{
"label": "Changelog",
"isExternal": true,
"href": "https://zuplo.com/changelog"
},
"articles/security",
{
"label": "Trust & Compliance",
"isExternal": true,
"href": "https://trust.zuplo.com"
}
]
Expand Down
25 changes: 25 additions & 0 deletions src/app/cli/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DocsLayout } from "@/components/DocsLayout";
import Link from "next/link";

export default async function Page() {
return (
<DocsLayout frontmatter={{ title: "Zuplo CLI" }} useRateSection={false}>
<p>
The Zuplo CLI, <code>zup</code>, provides convenient tooling for common
tasks that you might want to automate. You can use it to deploy zups
through CI/CD, create and update environment variables, manage your
tunnels, and more! It is powered by the{" "}
<Link
href="https://dev.zuplo.com/docs"
target="_blank"
rel="noopener noreferrer"
className="text-pink underline transition-colors hover:text-pink-hover"
>
Zuplo Developer API
</Link>{" "}
, which you can also call directly, if you want to create your own
tooling.
</p>
</DocsLayout>
);
}
2 changes: 2 additions & 0 deletions src/build/navigation.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const __filename = url.fileURLToPath(import.meta.url);
function buildNavSection(rawSection) {
let section = {
label: rawSection.label,
href: rawSection.href,
type: rawSection.type,
items: [],
};
if (!rawSection.items) {
Expand Down
60 changes: 38 additions & 22 deletions src/components/DocsHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client";

import { usePathname } from "next/navigation";

import { navigation } from "@/build/navigation.mjs";
import { NavCategory, NavItem, Section } from "@/lib/types";
import { NavCategory, Section } from "@/lib/types";
import Link from "next/link";
import ChevronRightIcon from "@/components/svgs/chevron-right.svg";
import { MobileTableOfContents } from "@/components/MobileTableOfContents";
import { useFindNavItemByLink } from "@/lib/hooks/useFindNavItemByLink";
import { nanoid } from "nanoid";

export function DocsHeader({
title,
Expand All @@ -15,32 +15,48 @@ export function DocsHeader({
title?: string;
tableOfContents?: Array<Section>;
}) {
let pathname = usePathname();

const findLink = (link: NavCategory | NavItem): boolean => {
if ("href" in link) {
return link.href === pathname.split("#")[0];
} else {
return link.items.some(findLink);
}
};

let section = navigation.find((section) => section.items.find(findLink));
const section = navigation.find((section) =>
section.items.find(useFindNavItemByLink),
);

if (!title && !section) {
return null;
}

const breadcrumbItems: Array<NavCategory> = [{ label: "Home", href: "/" }];

if (section) {
breadcrumbItems.push({
label: section.label,
href: section.href,
});
let currentSection = section;

while (currentSection?.items?.length) {
currentSection = currentSection.items.find(useFindNavItemByLink);

if (currentSection) {
breadcrumbItems.push({
label: currentSection.label,
href: currentSection?.href,
});
}
}
}

return (
<header className="mb-5">
<div className="mb-4 flex items-center gap-x-[3px] text-sm leading-6 tracking-wider text-gray-600 lg:mb-10">
<Link href="/">Home</Link>
{section && (
<>
<ChevronRightIcon />
<p>{section.label}</p>
</>
)}
<div className="mb-4 flex flex-wrap items-center gap-x-[3px] text-sm leading-6 tracking-wider text-gray-600 lg:mb-10">
{breadcrumbItems.map((item, index) => (
<div className="flex items-center" key={nanoid()}>
{!!item?.href ? (
<Link href={item.href}>{item.label}</Link>
) : (
<p>{item.label}</p>
)}
{index < breadcrumbItems.length - 1 && <ChevronRightIcon />}
</div>
))}
</div>

{tableOfContents && (
Expand Down
Loading

0 comments on commit b5a530c

Please sign in to comment.