mirror of
https://github.com/privacy-scaling-explorations/pse.dev.git
synced 2026-04-23 03:01:03 -04:00
fix: 🔍 Improve SEO, update projects & detail styles
This commit is contained in:
@@ -10,6 +10,7 @@ import { TailwindIndicator } from "@/components/tailwind-indicator"
|
||||
// import { ThemeProvider } from "@/components/theme-provider"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL("https://appliedzkp.org"),
|
||||
title: {
|
||||
default: siteConfig.name,
|
||||
template: `%s - ${siteConfig.name}`,
|
||||
|
||||
@@ -82,7 +82,7 @@ export default function IndexPage() {
|
||||
passHref
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<div className="border-b-2 border-orange text-base font-[500] uppercase">
|
||||
<div className="border-b-2 border-orange text-base font-medium uppercase">
|
||||
Say Hi On Discord
|
||||
</div>
|
||||
<ArrowRightUp color="black" />
|
||||
|
||||
@@ -1,102 +1,105 @@
|
||||
"use client"
|
||||
|
||||
import { Metadata, ResolvingMetadata } from "next"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { projects } from "@/data/projects"
|
||||
import GithubVector from "@/public/social-medias/github-fill.svg"
|
||||
import GlobalVector from "@/public/social-medias/global-line.svg"
|
||||
import TwitterVector from "@/public/social-medias/twitter-fill.svg"
|
||||
|
||||
import { projects } from "@/config/projects"
|
||||
import Breadcrumbs from "@/components/breadcrumbs"
|
||||
type PageProps = {
|
||||
params: { id: string }
|
||||
searchParams: { [key: string]: string | string[] | undefined }
|
||||
}
|
||||
|
||||
export default function ProjectDetailPage() {
|
||||
const router = usePathname()
|
||||
|
||||
const breadcrumbs = router
|
||||
.split("/")
|
||||
.slice(1)
|
||||
.map((part) => {
|
||||
const id = Number(part)
|
||||
|
||||
if (!isNaN(id)) {
|
||||
const project = projects.find((project) => project.id === id)
|
||||
|
||||
return project ? project.name : part
|
||||
} else {
|
||||
return part
|
||||
}
|
||||
})
|
||||
|
||||
const findProject = projects.filter(
|
||||
(project) => String(project.id) === router.split("/").slice(1)[1]
|
||||
export async function generateMetadata(
|
||||
{ params }: PageProps,
|
||||
parent: ResolvingMetadata
|
||||
): Promise<Metadata> {
|
||||
const currProject = projects.filter(
|
||||
(project) => String(project.id) === params.id
|
||||
)[0]
|
||||
|
||||
const { github, discord, twitter, website } = findProject.links
|
||||
return {
|
||||
title: currProject.name,
|
||||
description: currProject.tldr,
|
||||
openGraph: {
|
||||
images: [
|
||||
currProject.image
|
||||
? `/project-banners/${currProject.image}`
|
||||
: "/project-banners/fallback.webp",
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default function ProjectDetailPage({ params }: PageProps) {
|
||||
const currProject = projects.filter(
|
||||
(project) => String(project.id) === params.id
|
||||
)[0]
|
||||
|
||||
const { github, twitter, website } = currProject.links
|
||||
|
||||
return (
|
||||
<section className="flex flex-col items-center">
|
||||
<div className="relative flex h-auto w-full justify-center overflow-hidden bg-second-gradient md:h-[400px]">
|
||||
<div className="z-[11] flex w-full flex-col justify-center gap-5 p-[24px] md:w-[664px] md:p-0">
|
||||
<Breadcrumbs path={breadcrumbs} />
|
||||
<h1 className="text-2xl font-[700] md:text-3xl">
|
||||
{findProject.name}
|
||||
</h1>
|
||||
<div className="mx-auto flex h-auto w-full justify-center bg-second-gradient md:h-[272px]">
|
||||
<div className="flex flex-col gap-3 p-6 md:w-[700px]">
|
||||
<div className="flex gap-2 text-sm">
|
||||
<Link
|
||||
href="/projects"
|
||||
className="font-medium transition duration-100 hover:text-orange"
|
||||
>
|
||||
Project Library
|
||||
</Link>
|
||||
<p className="text-slate-500">/</p>
|
||||
<p className="text-slate-500">{currProject.name}</p>
|
||||
</div>
|
||||
<p className="p-2"></p>
|
||||
<h1 className="text-3xl font-bold md:text-4xl">{currProject.name}</h1>
|
||||
<div className="flex flex-wrap items-center justify-start gap-5">
|
||||
{github && (
|
||||
<Link
|
||||
href={findProject.links.github}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Link href={github} target="_blank" rel="noreferrer">
|
||||
<div className="flex items-center gap-2">
|
||||
<Image src={GithubVector} alt="bg" width={20} height={20} />
|
||||
<p>Github</p>
|
||||
<Image src={GithubVector} alt="" width={16} height={16} />
|
||||
<p className="text-slate-600">Github</p>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
{website && (
|
||||
<Link
|
||||
href={findProject.links.website}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Link href={website} target="_blank" rel="noreferrer">
|
||||
<div className="flex items-center gap-2">
|
||||
<Image src={GlobalVector} alt="bg" width={20} height={20} />
|
||||
<p>Website</p>
|
||||
<Image src={GlobalVector} alt="" width={16} height={16} />
|
||||
<p className="text-slate-600">Website</p>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
{twitter && (
|
||||
<Link
|
||||
href={findProject.links.twitter}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Link href={twitter} target="_blank" rel="noreferrer">
|
||||
<div className="flex items-center gap-2">
|
||||
<Image src={TwitterVector} alt="bg" width={20} height={20} />
|
||||
<p>Twitter</p>
|
||||
<Image src={TwitterVector} alt="" width={16} height={16} />
|
||||
<p className="text-slate-600">Twitter</p>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-5 w-full text-lg md:w-[612px]">{findProject.tldr}</p>
|
||||
<p className="text-slate-600">{currProject.tldr}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-center justify-center gap-5 bg-anakiwa px-[24px] py-10 md:px-0">
|
||||
{findProject.image ? (
|
||||
<div className="flex h-auto items-center justify-center">
|
||||
<div className="flex w-full flex-col items-center justify-center gap-5 bg-anakiwa px-6 py-10 md:px-0">
|
||||
<div className="w-[700px]">
|
||||
<div className="relative flex items-center justify-center overflow-hidden rounded-lg">
|
||||
<Image
|
||||
src={require(`@/public/project-banners/${findProject.image}`)}
|
||||
alt="bg"
|
||||
width={664}
|
||||
src={`/project-banners/${
|
||||
currProject.image ? currProject.image : "fallback.webp"
|
||||
}`}
|
||||
alt={`${currProject.name} banner`}
|
||||
width={1200}
|
||||
height={630}
|
||||
className="w-full rounded-t-lg object-cover"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<div className="flex w-full flex-col gap-5 py-10 text-base font-normal md:w-[664px] md:text-lg">
|
||||
<p>{findProject.description}</p>
|
||||
<div className="flex w-full flex-col gap-5 py-10 text-base font-normal leading-relaxed">
|
||||
<p>{currProject.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,20 +1,41 @@
|
||||
"use client"
|
||||
|
||||
import { Metadata } from "next"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { projects } from "@/data/projects"
|
||||
import GithubIcon from "@/public/social-medias/github-fill.svg"
|
||||
import GlobeIcon from "@/public/social-medias/global-line.svg"
|
||||
|
||||
export default function ProjectsPage() {
|
||||
const router = useRouter()
|
||||
export const metadata: Metadata = {
|
||||
title: "Project Library",
|
||||
description:
|
||||
"PSE is home to many projects, from cryptography research to developer tools, protocols and proof-of-concept applications.",
|
||||
}
|
||||
|
||||
// TODO: MAKE IT RANDOM - This would prob need to be state and so metadata would get cut
|
||||
// const randomizeProjects = (projects: any[]) => {
|
||||
// // efficient fisher-yates shuffle
|
||||
// const array = [...projects]
|
||||
// let currentIndex = array.length,
|
||||
// randomIndex
|
||||
// while (currentIndex !== 0) {
|
||||
// randomIndex = Math.floor(Math.random() * currentIndex)
|
||||
// currentIndex--
|
||||
// ;[array[currentIndex], array[randomIndex]] = [
|
||||
// array[randomIndex],
|
||||
// array[currentIndex],
|
||||
// ]
|
||||
// }
|
||||
// return array
|
||||
// }
|
||||
|
||||
export default function ProjectsPage() {
|
||||
return (
|
||||
<section>
|
||||
<div className="bg-second-gradient">
|
||||
<div className="container mx-auto py-12 lg:py-24">
|
||||
<h1 className="text-5xl font-bold">Explore the project library</h1>
|
||||
<h1 className="text-4xl font-bold md:text-5xl">
|
||||
Explore the project library
|
||||
</h1>
|
||||
<p className="p-2"></p>
|
||||
<p className="w-full text-lg md:w-[612px] md:text-xl">
|
||||
PSE is home to many projects, from cryptography research to
|
||||
@@ -31,68 +52,62 @@ export default function ProjectsPage() {
|
||||
const { id, image, links, name, tldr } = project
|
||||
const { github, website } = links
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
onClick={() => router.push(`/projects/${id}`)}
|
||||
className="flex h-[419px] w-[310px] cursor-pointer flex-col overflow-hidden rounded-lg border border-slate-900/20 transition duration-150 ease-in hover:scale-105"
|
||||
>
|
||||
{project.image.length > 0 ? (
|
||||
<Link href={`/projects/${id}`}>
|
||||
<div
|
||||
key={index}
|
||||
className="flex h-[419px] w-[310px] cursor-pointer flex-col overflow-hidden rounded-lg border border-slate-900/20 transition duration-150 ease-in hover:scale-105"
|
||||
>
|
||||
<Image
|
||||
src={require(`@/public/project-banners/${image}`)}
|
||||
alt={name}
|
||||
className="h-[163px] w-full rounded-t-lg object-cover"
|
||||
src={`/project-banners/${
|
||||
image ? image : "fallback.webp"
|
||||
}`}
|
||||
alt={`${name} banner`}
|
||||
width={1200}
|
||||
height={630}
|
||||
className="w-full rounded-t-lg object-cover"
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
src={require(`@/public/project-banners/fallback.webp`)}
|
||||
alt={name}
|
||||
className="h-[163px] w-full rounded-t-lg object-cover"
|
||||
/>
|
||||
)}
|
||||
<div className="flex h-full flex-col justify-between gap-5 rounded-b-lg bg-white p-5">
|
||||
<div className="flex flex-col justify-start gap-2">
|
||||
<h1 className="text-xl font-bold text-black">{name}</h1>
|
||||
<p className="text-slate-900/80">{tldr}</p>
|
||||
</div>
|
||||
<div
|
||||
className="mr-auto flex items-center justify-start gap-2"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{github && (
|
||||
<Link
|
||||
href={`${github}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="hover:opacity-60"
|
||||
>
|
||||
<Image
|
||||
src={GithubIcon}
|
||||
alt="githubVector"
|
||||
className="cursor-pointer"
|
||||
width={18}
|
||||
height={18}
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
{website && (
|
||||
<Link
|
||||
href={`${website}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="hover:opacity-60"
|
||||
>
|
||||
<Image
|
||||
src={GlobeIcon}
|
||||
className="cursor-pointer"
|
||||
alt="globalVector"
|
||||
width={18}
|
||||
height={18}
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
<div className="flex h-full flex-col justify-between gap-5 rounded-b-lg bg-white p-5">
|
||||
<div className="flex flex-col justify-start gap-2">
|
||||
<h1 className="text-xl font-bold text-black">{name}</h1>
|
||||
<p className="text-slate-900/80">{tldr}</p>
|
||||
</div>
|
||||
<div className="mr-auto flex items-center justify-start gap-2">
|
||||
{github && (
|
||||
<Link
|
||||
href={`${github}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="hover:opacity-60"
|
||||
>
|
||||
<Image
|
||||
src={GithubIcon}
|
||||
alt="githubVector"
|
||||
className="cursor-pointer"
|
||||
width={18}
|
||||
height={18}
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
{website && (
|
||||
<Link
|
||||
href={`${website}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="hover:opacity-60"
|
||||
>
|
||||
<Image
|
||||
src={GlobeIcon}
|
||||
className="cursor-pointer"
|
||||
alt="globalVector"
|
||||
width={18}
|
||||
height={18}
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ export function SiteFooter() {
|
||||
by the Ethereum Foundation.
|
||||
</h1>
|
||||
</div>
|
||||
<div className="flex w-full flex-col gap-5 px-[32px] text-base font-[500]">
|
||||
<div className="flex w-full flex-col gap-5 px-[32px] text-base font-medium">
|
||||
<Link href={"/"} className="border-b-2 border-[#171C1B] py-5">
|
||||
HOME
|
||||
</Link>
|
||||
|
||||
@@ -46,7 +46,7 @@ export function SiteHeaderMobile() {
|
||||
height={24}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col gap-5 px-[16px] text-base font-[500]">
|
||||
<div className="flex w-full flex-col gap-5 px-[16px] text-base font-medium">
|
||||
<NextLink
|
||||
href={"/"}
|
||||
onClick={() => setHeader(false)}
|
||||
|
||||
Reference in New Issue
Block a user