From d427d1b1958b95b1ce9c8f647060de3f637a7285 Mon Sep 17 00:00:00 2001 From: Kalidou Diagne Date: Mon, 21 Oct 2024 01:11:27 +0100 Subject: [PATCH] side navbar contents --- .../projects/sections/ProjectContent.tsx | 3 +- app/i18n/locales/en/common.json | 1 + components/project/project-detail-tags.tsx | 4 +- components/project/project-extra-links.tsx | 6 +- components/ui/markdown.tsx | 12 +++ components/wiki-side-navigation.tsx | 75 ++++++++++++++++++- data/projects.ts | 2 - data/projects/example.ts | 27 ------- 8 files changed, 93 insertions(+), 37 deletions(-) delete mode 100644 data/projects/example.ts diff --git a/app/[lang]/projects/sections/ProjectContent.tsx b/app/[lang]/projects/sections/ProjectContent.tsx index 33df597..f2b5531 100644 --- a/app/[lang]/projects/sections/ProjectContent.tsx +++ b/app/[lang]/projects/sections/ProjectContent.tsx @@ -60,6 +60,7 @@ export const ProjectContent = ({ {content?.description?.length > 0 && ( )} @@ -186,7 +187,7 @@ export const ProjectContent = ({ project={project} lang={lang} /> -
+
{ const TagsWrapper = ({ label, children }: TagsProps) => { return ( -
-

{label}

+
+

{label}

{children}
) diff --git a/components/project/project-extra-links.tsx b/components/project/project-extra-links.tsx index e9995dc..380ed44 100644 --- a/components/project/project-extra-links.tsx +++ b/components/project/project-extra-links.tsx @@ -63,9 +63,9 @@ export default function ProjectExtraLinks({ if (!links.length) return null // no links hide the section return ( -
+
-

{label}

+

{label}

{links.map((link: ActionLinkTypeLink, index) => { @@ -89,7 +89,7 @@ export default function ProjectExtraLinks({ } return ( -
+
{Object.entries(ExtraLinkLabelMapping).map(([key]) => { const links = extraLinks[key as ProjectExtraLinkType] ?? [] return ( diff --git a/components/ui/markdown.tsx b/components/ui/markdown.tsx index 291cb2a..da3569b 100644 --- a/components/ui/markdown.tsx +++ b/components/ui/markdown.tsx @@ -2,12 +2,24 @@ import React from "react" import ReactMarkdown, { Components } from "react-markdown" import remarkGfm from "remark-gfm" +const generateSectionId = (text: string) => { + return text.toLowerCase().replace(/[^a-z0-9]+/g, "-") +} + export const createMarkdownElement = ( tag: keyof JSX.IntrinsicElements, props: any ) => React.createElement(tag, { ...props, + ref: (node: HTMLElement | null) => { + if (node && node.textContent) { + node.setAttribute( + "data-section-id", + generateSectionId(node.textContent) + ) + } + }, }) const Table = (props: any) => { diff --git a/components/wiki-side-navigation.tsx b/components/wiki-side-navigation.tsx index 0936cba..757dc55 100644 --- a/components/wiki-side-navigation.tsx +++ b/components/wiki-side-navigation.tsx @@ -2,9 +2,12 @@ import { useEffect, useRef, useState } from "react" +import { ProjectExtraLinkType } from "@/lib/types" import { cn } from "@/lib/utils" import { useTranslation } from "@/app/i18n/client" +import { Icons } from "./icons" + interface Section { level: number text: string @@ -15,12 +18,14 @@ interface WikiSideNavigationProps { className?: string lang?: string content?: string + project?: any } export const WikiSideNavigation = ({ className, lang = "en", content = "", + project, }: WikiSideNavigationProps) => { const { t } = useTranslation(lang, "common") const [sections, setSections] = useState([]) @@ -46,6 +51,10 @@ export const WikiSideNavigation = ({ } setSections(extractedSections) + // Set the first section as active by default + if (extractedSections.length > 0) { + setActiveSection(extractedSections[0].id) + } }, [content]) // Set up intersection observer @@ -59,7 +68,7 @@ export const WikiSideNavigation = ({ observerRef.current = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { - setActiveSection(entry.target.id) + setActiveSection(entry.target.getAttribute("data-section-id")) } }) }, observerOptions) @@ -89,9 +98,37 @@ export const WikiSideNavigation = ({ top: offsetPosition, behavior: "smooth", }) + setActiveSection(sectionId) } } + const ExtraLinkLabelMapping: Record< + ProjectExtraLinkType, + { + label: string + icon?: any + } + > = { + buildWith: { + label: t("buildWith"), + icon: , + }, + play: { + label: t("tryItOut"), + icon: , + }, + research: { + label: t("deepDiveResearch"), + icon: , + }, + learn: { + label: t("learnMore"), + }, + } + + const { extraLinks = {} } = project + const hasExtraLinks = Object.keys(extraLinks).length > 0 + if (sections.length === 0 || content.length === 0) return null return ( @@ -105,7 +142,7 @@ export const WikiSideNavigation = ({
  • ))} + {Object.entries(ExtraLinkLabelMapping).map(([key]) => { + const links = extraLinks[key as ProjectExtraLinkType] ?? [] + // @ts-ignore + const { label } = ExtraLinkLabelMapping?.[key as any] ?? {} + if (!links.length) return null // no links hide the section + return ( +
  • scrollToSection(key)} + className={cn( + "flex h-8 items-center border-l-2 border-l-anakiwa-200 px-3 duration-200 cursor-pointer", + { + "border-l-anakiwa-500 text-anakiwa-500 font-medium": + activeSection === key, + } + )} + > + {label} +
  • + ) + })} +
  • scrollToSection("edit-this-page")} + className={cn( + "flex h-8 items-center border-l-2 border-l-anakiwa-200 px-3 duration-200 cursor-pointer", + { + "border-l-anakiwa-500 text-anakiwa-500 font-medium": + activeSection === "edit-this-page", + } + )} + > + Edit this page +
  • diff --git a/data/projects.ts b/data/projects.ts index ba6d6e1..c85a243 100644 --- a/data/projects.ts +++ b/data/projects.ts @@ -11,7 +11,6 @@ import { discreetly } from "./projects/discreetly" import { dslWorkingGroup } from "./projects/dsl-working-group" import { ECIPHalo2 } from "./projects/ecip-halo2" import { eigenTrust } from "./projects/eigen-trust" -import { example } from "./projects/example" import { Interep } from "./projects/interep" import { jubmoji } from "./projects/jubmoji" import { maci } from "./projects/maci" @@ -47,7 +46,6 @@ import { zkp2p } from "./projects/zkp2p" * Every 'description' props supports markdown syntax https://www.markdownguide.org/basic-syntax/ */ export const projects: ProjectInterface[] = [ - example, rln, zkitter, maci, diff --git a/data/projects/example.ts b/data/projects/example.ts deleted file mode 100644 index 3b921d6..0000000 --- a/data/projects/example.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ProjectInterface, ProjectStatus } from "@/lib/types" - -export const example: ProjectInterface = { - id: "project_name", - image: "", - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - name: "This is an example of the project", - content: { - en: { - tldr: "Short description", - description: ` -## Heading - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - `, - }, - }, - tags: { - keywords: [], - themes: [], - types: [], - builtWith: [], - }, -}