|
1 | 1 | import React, { useEffect, useState } from "react"; |
| 2 | +import { graphql, useStaticQuery } from "gatsby"; |
2 | 3 |
|
3 | | -import { content } from "./content"; |
4 | 4 | import Button from "../../reusecore/Button"; |
5 | 5 | import PaginationWrapper from "./pagination.style"; |
6 | 6 |
|
| 7 | +const STABLE_ROUTES = [ |
| 8 | + // Getting Started |
| 9 | + { link: "/projects/sistent/getting-started/about", text: "About" }, |
| 10 | + { link: "/projects/sistent/getting-started/installation", text: "Installation" }, |
| 11 | + { link: "/projects/sistent/getting-started/usage", text: "Usage" }, |
| 12 | + { link: "/projects/sistent/getting-started/tokens", text: "Tokens" }, |
| 13 | + |
| 14 | + // Identity |
| 15 | + { link: "/projects/sistent/identity/color", text: "Colors" }, |
| 16 | + { link: "/projects/sistent/identity/color/guidance", text: "Colors" }, |
| 17 | + { link: "/projects/sistent/identity/color/code", text: "Colors" }, |
| 18 | + { link: "/projects/sistent/identity/spacing", text: "Spacing" }, |
| 19 | + { link: "/projects/sistent/identity/spacing/guidance", text: "Spacing" }, |
| 20 | + { link: "/projects/sistent/identity/spacing/code", text: "Spacing" }, |
| 21 | + { link: "/projects/sistent/identity/typography", text: "Typography" }, |
| 22 | + { link: "/projects/sistent/identity/typography/guidance", text: "Typography" }, |
| 23 | + { link: "/projects/sistent/identity/typography/code", text: "Typography" }, |
| 24 | +]; |
| 25 | + |
| 26 | +const PAGE_TYPE_ORDER = { |
| 27 | + overview: 1, |
| 28 | + guidance: 2, |
| 29 | + code: 3, |
| 30 | +}; |
| 31 | + |
7 | 32 | const SistentPagination = () => { |
8 | 33 | const [currentPage, setCurrentPage] = useState(0); |
9 | 34 |
|
| 35 | + const data = useStaticQuery(graphql` |
| 36 | + query SistentPaginationNav { |
| 37 | + allMdx( |
| 38 | + filter: { |
| 39 | + fields: { collection: { eq: "sistent" } } |
| 40 | + } |
| 41 | + ) { |
| 42 | + nodes { |
| 43 | + frontmatter { |
| 44 | + name |
| 45 | + component |
| 46 | + published |
| 47 | + } |
| 48 | + fields { |
| 49 | + slug |
| 50 | + pageType |
| 51 | + } |
| 52 | + } |
| 53 | + } |
| 54 | + } |
| 55 | + `); |
| 56 | + |
| 57 | + // Compile set of published components based on overview pages |
| 58 | + const publishedComponents = new Set(); |
| 59 | + data.allMdx.nodes.forEach((node) => { |
| 60 | + if (node.fields.pageType === "overview" && node.frontmatter.published === true) { |
| 61 | + publishedComponents.add(node.frontmatter.component); |
| 62 | + } |
| 63 | + }); |
| 64 | + |
| 65 | + // Map, filter out drafts, and group by tab order: overview -> guidance -> code |
| 66 | + const dynamicRoutes = data.allMdx.nodes |
| 67 | + .map((node) => ({ |
| 68 | + componentSlug: node.frontmatter.component, |
| 69 | + name: node.frontmatter.name || node.frontmatter.component, |
| 70 | + link: node.fields.slug, |
| 71 | + pageType: node.fields.pageType, |
| 72 | + })) |
| 73 | + .filter((node) => publishedComponents.has(node.componentSlug)) |
| 74 | + .sort((a, b) => { |
| 75 | + if (a.componentSlug !== b.componentSlug) { |
| 76 | + return (a.componentSlug || "").localeCompare(b.componentSlug || ""); |
| 77 | + } |
| 78 | + return ( |
| 79 | + (PAGE_TYPE_ORDER[a.pageType] || 99) - (PAGE_TYPE_ORDER[b.pageType] || 99) |
| 80 | + ); |
| 81 | + }); |
| 82 | + |
| 83 | + const fullContentArray = [...STABLE_ROUTES, ...dynamicRoutes]; |
| 84 | + |
10 | 85 | useEffect(() => { |
11 | 86 | const path = window.location.pathname; |
12 | | - const index = content.findIndex((x) => x.link === path); |
| 87 | + // Handle trajectory slashes |
| 88 | + const cleanPath = path.endsWith("/") && path.length > 1 ? path.slice(0, -1) : path; |
| 89 | + const index = fullContentArray.findIndex((x) => x.link === cleanPath); |
13 | 90 | setCurrentPage(index); |
14 | | - }, []); |
| 91 | + }, [fullContentArray]); |
15 | 92 |
|
16 | 93 | return ( |
17 | 94 | <PaginationWrapper> |
18 | 95 | {currentPage > 0 ? ( |
19 | | - <Button $secondary $url={content[currentPage - 1]?.link}> |
| 96 | + <Button $secondary $url={fullContentArray[currentPage - 1]?.link}> |
20 | 97 | ← Previous |
21 | 98 | </Button> |
22 | | - ) : null} |
| 99 | + ) : <div />} |
23 | 100 |
|
24 | | - {currentPage < content.length - 1 ? ( |
25 | | - <Button $primary $url={content[currentPage + 1]?.link}> |
| 101 | + {currentPage !== -1 && currentPage < fullContentArray.length - 1 ? ( |
| 102 | + <Button $primary $url={fullContentArray[currentPage + 1]?.link}> |
26 | 103 | Next → |
27 | 104 | </Button> |
28 | | - ) : null} |
| 105 | + ) : <div />} |
29 | 106 | </PaginationWrapper> |
30 | 107 | ); |
31 | 108 | }; |
|
0 commit comments