side navbar contents

This commit is contained in:
Kalidou Diagne
2024-10-21 01:11:27 +01:00
parent a398e75c54
commit d427d1b195
8 changed files with 93 additions and 37 deletions

View File

@@ -60,6 +60,7 @@ export const ProjectContent = ({
{content?.description?.length > 0 && (
<WikiSideNavigation
className="hidden lg:block"
project={project}
content={content?.description}
/>
)}
@@ -186,7 +187,7 @@ export const ProjectContent = ({
project={project}
lang={lang}
/>
<div className="lg:col-start-2">
<div data-section-id="edit-this-page" className="lg:col-start-2">
<Link
href={editPageURL}
target="_blank"

View File

@@ -61,6 +61,7 @@
"learnMore": "Learn more",
"learnMoreDiscord": "Join our Discord to learn more about our programs and other educational opportunities!",
"buildWithThisTool": "Build with this tool",
"buildWith": "Build with",
"deepDiveResearch": "Dive deeper into the research",
"searchProjectPlaceholder": "Search project title or keyword",
"close": "Close",

View File

@@ -20,8 +20,8 @@ interface TagsProps extends HtmlHTMLAttributes<HTMLDivElement> {
const TagsWrapper = ({ label, children }: TagsProps) => {
return (
<div className="flex flex-col items-start md:gap-2">
<h3 className="py-2 text-[22px] font-bold text-tuatara-700">{label}</h3>
<div className="flex flex-col items-start gap-2">
<h3 className="text-[22px] font-bold text-tuatara-700">{label}</h3>
{children}
</div>
)

View File

@@ -63,9 +63,9 @@ export default function ProjectExtraLinks({
if (!links.length) return null // no links hide the section
return (
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-2" data-section-id={id}>
<div className="flex items-center gap-2">
<p className="py-2 text-[22px] font-bold text-tuatara-700">{label}</p>
<p className="text-[22px] font-bold text-tuatara-700">{label}</p>
</div>
<div className="flex flex-col items-start gap-2">
{links.map((link: ActionLinkTypeLink, index) => {
@@ -89,7 +89,7 @@ export default function ProjectExtraLinks({
}
return (
<div className="flex flex-col gap-8 py-4">
<div className="flex flex-col gap-8">
{Object.entries(ExtraLinkLabelMapping).map(([key]) => {
const links = extraLinks[key as ProjectExtraLinkType] ?? []
return (

View File

@@ -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) => {

View File

@@ -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<Section[]>([])
@@ -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: <Icons.hammer />,
},
play: {
label: t("tryItOut"),
icon: <Icons.hand />,
},
research: {
label: t("deepDiveResearch"),
icon: <Icons.readme />,
},
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 = ({
<li
key={index}
className={cn(
"flex h-8 items-center border-l-2 border-l-anakiwa-200 px-3 duration-200",
"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 === section.id,
@@ -120,6 +157,40 @@ export const WikiSideNavigation = ({
</button>
</li>
))}
{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 (
<li
key={key}
onClick={() => 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}
</li>
)
})}
<li
key="edit"
onClick={() => 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
</li>
</ul>
</aside>
</div>

View File

@@ -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,

View File

@@ -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: [],
},
}