cleanup site meta tags (#476)

This commit is contained in:
Kalidou Diagne
2025-06-20 13:30:07 +01:00
committed by GitHub
parent 8ea062d57b
commit 1a3e82eb6c
7 changed files with 116 additions and 94 deletions

View File

@@ -10,6 +10,12 @@ import { Divider } from "@/components/divider"
import { Icons } from "@/components/icons"
import { LABELS } from "@/app/labels"
import { interpolate } from "@/lib/utils"
import { Metadata } from "next"
export const metadata: Metadata = {
title: "About",
description: "About the Privacy & Scaling Explorations community",
}
export default async function AboutPage() {
const principles = LABELS.ABOUT_PAGE.PRINCIPLES

View File

@@ -12,6 +12,7 @@ import { LABELS } from "../labels"
export const metadata: Metadata = {
title: "404: Page Not Found",
description: "The requested page could not be found",
}
export default function NotFound() {

View File

@@ -2,6 +2,7 @@ import { Metadata } from "next"
import { ProjectInterface } from "@/lib/types"
import { ProjectContent } from "../sections/ProjectContent"
import { getProjects, Project } from "@/lib/content"
type PageProps = {
params: { id: string }
@@ -12,18 +13,22 @@ export interface ProjectProps {
project: ProjectInterface
}
/*
export async function generateMetadata({
params,
}: PageProps): Promise<Metadata> {
const response = await fetch("/api/projects")
const projects = await response.json()
const projects = await getProjects()
const project = projects.find(
(p: ProjectInterface) =>
(p: Project) =>
String(p.id?.toLowerCase()) === params.id.toString().toLowerCase()
)
if (!project) {
return {
title: "Project Not Found",
description: "The requested project could not be found",
}
}
const content = project?.content
const imageUrl =
(project?.image ?? "")?.length > 0
@@ -43,7 +48,7 @@ export async function generateMetadata({
],
},
}
}*/
}
export default async function ProjectDetailPage({ params }: PageProps) {
return <ProjectContent id={params?.id?.toLowerCase()} />

View File

@@ -1,9 +1,6 @@
"use client"
import { useCallback, useEffect, useRef, useState } from "react"
import Link from "next/link"
import { cn, interpolate } from "@/lib/utils"
import { interpolate } from "@/lib/utils"
import { siteConfig } from "@/config/site"
import { LABELS } from "@/app/labels"
@@ -15,6 +12,13 @@ import { Button } from "@/components/ui/button"
import { Label } from "@/components/ui/label"
import ResourcesContent from "@/content/resources.md"
import { Metadata } from "next"
import { ResourceNav } from "@/components/resources/ResourceNav"
export const metadata: Metadata = {
title: "Resources",
description: "Resources for the Privacy & Scaling Explorations community",
}
interface ResourceItemProps {
label: string
@@ -85,87 +89,6 @@ const ResourceCard = ({ id, title, children }: ResourceCardProps) => {
)
}
const ResourceNav = () => {
const SCROLL_OFFSET = 80
const [activeId, setActiveId] = useState("")
const [isManualScroll, setIsManualScroll] = useState(false)
const ID_LABELS_MAPPING: Record<string, string> = {
"get-involved": LABELS.RESOURCES_PAGE.NAV.GET_INVOLVED,
learn: LABELS.RESOURCES_PAGE.NAV.LEARN,
build: LABELS.RESOURCES_PAGE.NAV.BUILD,
design: LABELS.RESOURCES_PAGE.NAV.DESIGN,
}
const sectionsRef = useRef<NodeListOf<HTMLElement> | null>(null) // sections are constant so useRef might be better here
useEffect(() => {
if (sectionsRef.current === null)
sectionsRef.current = document.querySelectorAll("div[data-section]")
if (!activeId) setActiveId("get-involved")
const handleScroll = () => {
if (isManualScroll) return
sectionsRef.current?.forEach((section: any) => {
const sectionTop = section.offsetTop - SCROLL_OFFSET
if (window.scrollY >= sectionTop && window.scrollY > 0) {
setActiveId(section.getAttribute("id"))
}
})
}
window.addEventListener("scroll", handleScroll)
return () => window.removeEventListener("scroll", handleScroll)
}, [activeId, isManualScroll])
const scrollToId = useCallback((id: string) => {
const element = document.getElementById(id)
const top = element?.offsetTop ?? 0
if (element) {
setActiveId(id) // active clicked id
setIsManualScroll(true) // tell the window event listener to ignore this scrolling
window?.scrollTo({
behavior: "smooth",
top: (top ?? 0) - SCROLL_OFFSET,
})
}
setTimeout(() => setIsManualScroll(false), 800)
}, [])
return (
<div className="flex flex-col gap-6 p-8">
<div className="flex flex-col gap-4">
<h6 className="font-display text-lg font-bold text-secondary dark:text-white">
{LABELS.RESOURCES_PAGE.ON_THIS_PAGE}
</h6>
<ul className="text-normal font-sans text-primary">
{Object.entries(ID_LABELS_MAPPING).map(([id, label]) => {
const active = id === activeId
return (
<li
key={id}
onClick={() => {
scrollToId(id)
}}
data-id={id}
className={cn(
"flex h-8 cursor-pointer items-center border-l-2 border-l-anakiwa-200 px-3 duration-200",
{
"border-l-anakiwa-500 text-anakiwa-500 font-medium": active,
}
)}
>
{label}
</li>
)
})}
</ul>
</div>
</div>
)
}
export default function ResourcePage() {
return (
<div className="flex flex-col">

View File

@@ -54,8 +54,9 @@ export const viewport: Viewport = {
export const metadata: Metadata = {
title: {
default: siteConfig.name,
template: `%s | ${siteConfig.name}`,
template: "%s | PSE",
},
metadataBase: new URL("https://pse.dev"),
description: siteConfig.description,
keywords: [
"Privacy & Scaling Explorations",

View File

@@ -0,0 +1,86 @@
"use client"
import { LABELS } from "@/app/labels"
import { useCallback, useEffect, useRef, useState } from "react"
import { cn } from "@/lib/utils"
export const ResourceNav = () => {
const SCROLL_OFFSET = 80
const [activeId, setActiveId] = useState("")
const [isManualScroll, setIsManualScroll] = useState(false)
const ID_LABELS_MAPPING: Record<string, string> = {
"get-involved": LABELS.RESOURCES_PAGE.NAV.GET_INVOLVED,
learn: LABELS.RESOURCES_PAGE.NAV.LEARN,
build: LABELS.RESOURCES_PAGE.NAV.BUILD,
design: LABELS.RESOURCES_PAGE.NAV.DESIGN,
}
const sectionsRef = useRef<NodeListOf<HTMLElement> | null>(null) // sections are constant so useRef might be better here
useEffect(() => {
if (sectionsRef.current === null)
sectionsRef.current = document.querySelectorAll("div[data-section]")
if (!activeId) setActiveId("get-involved")
const handleScroll = () => {
if (isManualScroll) return
sectionsRef.current?.forEach((section: any) => {
const sectionTop = section.offsetTop - SCROLL_OFFSET
if (window.scrollY >= sectionTop && window.scrollY > 0) {
setActiveId(section.getAttribute("id"))
}
})
}
window.addEventListener("scroll", handleScroll)
return () => window.removeEventListener("scroll", handleScroll)
}, [activeId, isManualScroll])
const scrollToId = useCallback((id: string) => {
const element = document.getElementById(id)
const top = element?.offsetTop ?? 0
if (element) {
setActiveId(id) // active clicked id
setIsManualScroll(true) // tell the window event listener to ignore this scrolling
window?.scrollTo({
behavior: "smooth",
top: (top ?? 0) - SCROLL_OFFSET,
})
}
setTimeout(() => setIsManualScroll(false), 800)
}, [])
return (
<div className="flex flex-col gap-6 p-8">
<div className="flex flex-col gap-4">
<h6 className="font-display text-lg font-bold text-secondary dark:text-white">
{LABELS.RESOURCES_PAGE.ON_THIS_PAGE}
</h6>
<ul className="text-normal font-sans text-primary">
{Object.entries(ID_LABELS_MAPPING).map(([id, label]) => {
const active = id === activeId
return (
<li
key={id}
onClick={() => {
scrollToId(id)
}}
data-id={id}
className={cn(
"flex h-8 cursor-pointer items-center border-l-2 border-l-anakiwa-200 px-3 duration-200",
{
"border-l-anakiwa-500 text-anakiwa-500 font-medium": active,
}
)}
>
{label}
</li>
)
})}
</ul>
</div>
</div>
)
}

View File

@@ -1,7 +1,7 @@
export type SiteConfig = typeof siteConfig
export const siteConfig = {
name: "PSE",
name: "Privacy & Scaling Explorations",
description:
"Enhancing Ethereum through cryptographic research and collective experimentation.",
url: "https://pse.dev",