Merge branch 'main' into fix-and-update-design

This commit is contained in:
Kalidou Diagne
2024-01-23 19:39:38 +00:00
20 changed files with 2786 additions and 108 deletions

View File

@@ -1,4 +1,4 @@
FROM node:18-alpine as builder
FROM node:18-alpine3.18 as builder
RUN apk add --no-cache git curl
WORKDIR /builder
@@ -8,7 +8,7 @@ RUN pnpm install
RUN pnpm build
# Create image by copying build artifacts
FROM node:18-alpine as runner
FROM node:18-alpine3.18 as runner
RUN npm i -g pnpm
USER node

86
app/[lang]/layout.tsx Normal file
View File

@@ -0,0 +1,86 @@
import "@/styles/globals.css"
import { Metadata } from "next"
import Script from "next/script"
import { siteConfig } from "@/config/site"
import { fontDisplay, fontSans } from "@/lib/fonts"
import { SiteFooter } from "@/components/site-footer"
import { SiteHeader } from "@/components/site-header"
import { TailwindIndicator } from "@/components/tailwind-indicator"
import { fallbackLng, languages } from "../i18n/settings"
export async function generateStaticParams() {
return languages.map((language) => ({ language }))
}
export const metadata: Metadata = {
metadataBase: new URL("https://appliedzkp.org"),
title: {
default: siteConfig.name,
template: `%s - ${siteConfig.name}`,
},
description: siteConfig.description,
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "white" },
{ media: "(prefers-color-scheme: dark)", color: "black" },
],
icons: {
icon: "/favicon.svg",
shortcut: "/favicon.svg",
apple: "/apple-touch-icon.png",
},
openGraph: {
images: [
{
url: "/og-image.png",
width: 1200,
height: 630,
},
],
},
}
interface RootLayoutProps {
children: React.ReactNode
params: any
}
export default function RootLayout({ children, params }: RootLayoutProps) {
const lang = params.lang ?? fallbackLng
return (
<>
<html
lang={lang}
className={`${fontSans.variable} ${fontDisplay.variable}`}
suppressHydrationWarning
>
<Script id="matomo-tracking" strategy="afterInteractive">
{`
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://psedev.matomo.cloud/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src='//cdn.matomo.cloud/psedev.matomo.cloud/matomo.js'; s.parentNode.insertBefore(g,s);
})();
`}
</Script>
<head />
<body className={"min-h-screen bg-background antialiased"}>
<div className="relative flex min-h-screen flex-col">
<SiteHeader lang={lang} />
<div className="flex-1">{children}</div>
<SiteFooter lang={lang} />
</div>
<TailwindIndicator />
</body>
</html>
</>
)
}

View File

@@ -2,7 +2,6 @@
import Image from "next/image"
import Link from "next/link"
import { useParams } from "next/navigation"
import PSELogo from "@/public/icons/archstar.webp"
import { motion } from "framer-motion"
@@ -16,8 +15,7 @@ import { WhatWeDo } from "@/components/sections/WhatWeDo"
import { useTranslation } from "../i18n/client"
import { LocaleTypes } from "../i18n/settings"
export default function IndexPage() {
const lang = useParams()?.locale as LocaleTypes
export default function IndexPage({ params: { lang } }: any) {
const { t } = useTranslation(lang, "homepage")
const { t: ct } = useTranslation(lang, "common")

View File

@@ -26,7 +26,7 @@ export const i18n = i18next
)
.init({
...getOptions(),
debug: true,
debug: false,
lng: undefined, // let detect the language on client side
detection: {
order: ["path", "htmlTag", "cookie", "navigator"],
@@ -45,7 +45,6 @@ export function useTranslation(
if (runsOnServerSide && lng && i18n.resolvedLanguage !== lng) {
i18n.changeLanguage(lng)
} else {
return ret
// eslint-disable-next-line react-hooks/rules-of-hooks
const [activeLng, setActiveLng] = useState(i18n.resolvedLanguage)
// eslint-disable-next-line react-hooks/rules-of-hooks

View File

@@ -1,4 +1,6 @@
{
"siteTitle": "Privacy & Scaling Explorations",
"siteDescription": "Enhancing Ethereum through cryptographic research and collective experimentation.",
"menu": {
"home": "Home",
"projectLibrary": "Project Library",

View File

@@ -6,9 +6,26 @@ export type LocaleTypes = (typeof languages)[number]
export const defaultNS = "translation"
export const cookieName = "i18next"
export const LanguageMapping: Record<string, string> = {
en: "English",
it: "Italiano",
ko: "한국어",
fr: "Français",
"zh-CN": "中文",
es: "Español",
}
export const languagesItems: { label: string; value: string }[] =
Object.entries(LanguageMapping).map(([value, label]) => {
return {
label,
value,
}
}) ?? []
export function getOptions(lng = fallbackLng, ns = defaultNS): InitOptions {
return {
// debug: true,
debug: false,
supportedLngs: languages,
fallbackLng,
lng,

View File

@@ -1,21 +1,14 @@
import "@/styles/globals.css"
import { Metadata } from "next"
import Script from "next/script"
import { siteConfig } from "@/config/site"
import { fontDisplay, fontSans } from "@/lib/fonts"
import { SiteFooter } from "@/components/site-footer"
import { SiteHeader } from "@/components/site-header"
import { TailwindIndicator } from "@/components/tailwind-indicator"
import { fallbackLng, languages } from "./i18n/settings"
import { languages } from "./i18n/settings"
export async function generateStaticParams() {
return languages.map((language) => ({ language }))
}
// import { ThemeProvider } from "@/components/theme-provider"
export const metadata: Metadata = {
metadataBase: new URL("https://appliedzkp.org"),
title: {
@@ -45,45 +38,9 @@ export const metadata: Metadata = {
interface RootLayoutProps {
children: React.ReactNode
params: any
params?: any
}
export default function RootLayout({
children,
params: { lang = fallbackLng },
}: RootLayoutProps) {
return (
<>
<html
lang={lang}
className={`${fontSans.variable} ${fontDisplay.variable}`}
suppressHydrationWarning
>
<Script id="matomo-tracking" strategy="afterInteractive">
{`
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://psedev.matomo.cloud/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src='//cdn.matomo.cloud/psedev.matomo.cloud/matomo.js'; s.parentNode.insertBefore(g,s);
})();
`}
</Script>
<head />
<body className={"min-h-screen bg-background antialiased"}>
<div className="relative flex min-h-screen flex-col">
<SiteHeader lang={lang} />
<div className="flex-1">{children}</div>
<SiteFooter lang={lang} />
</div>
<TailwindIndicator />
</body>
</html>
</>
)
export default function RootLayout({ children, params }: RootLayoutProps) {
return <>{children}</>
}

View File

@@ -47,7 +47,7 @@ export default function NotFound({ lang }: LangProps["params"]) {
</span>
</div>
</div>
<Link href={`/${lang}`} className="mx-auto">
<Link href="/" className="mx-auto">
<Button variant="black">{t("goToHome")}</Button>
</Link>
</div>

View File

@@ -6,17 +6,19 @@ import { usePathname } from "next/navigation"
import PSELogo from "@/public/logos/header-logo.svg"
import { NavItem } from "@/types/nav"
import { LocaleTypes, fallbackLng } from "@/app/i18n/settings"
export interface MainNavProps {
items: NavItem[]
lang?: LocaleTypes
}
export function MainNav({ items }: MainNavProps) {
export function MainNav({ items, lang = fallbackLng }: MainNavProps) {
const router = usePathname()
return (
<div className="flex gap-6 md:gap-10">
<Link href="/" className="flex items-center space-x-2">
<Link href={`/${lang}`} className="flex items-center space-x-2">
<Image src={PSELogo} alt="PSE Logo" width={32} height={32} />
</Link>
<nav className="hidden items-center gap-6 md:flex">

View File

@@ -3,11 +3,13 @@
import { useState } from "react"
import NextImage from "next/image"
import NextLink from "next/link"
import Link from "next/link"
import CloseVector from "@/public/icons/close-fill.svg"
import HeaderVector from "@/public/icons/menu-burger.svg"
import { LangProps } from "@/types/common"
import { siteConfig } from "@/config/site"
import { cn } from "@/lib/utils"
import {
Discord,
Github,
@@ -15,9 +17,55 @@ import {
Twitter,
} from "@/components/svgs/social-medias"
import { useTranslation } from "@/app/i18n/client"
import { LanguageMapping, languagesItems } from "@/app/i18n/settings"
import { Icons } from "./icons"
const LanguageSwitcher = ({ lang }: LangProps["params"]) => {
const [isOpen, setIsOpen] = useState(false)
if (!siteConfig?.showLanguageSwitcher) return null
return (
<div className="flex flex-col border-b-2 border-white px-[14px] py-[16px] pt-0">
<button
onClick={() => {
setIsOpen(!isOpen)
}}
type="button"
className="flex items-center gap-2 uppercase"
>
<Icons.globe className="text-white" size={22} fill="white" />
<span className="text-base font-medium uppercase text-white">
{LanguageMapping[lang] ?? LanguageMapping["en"]}
</span>
<Icons.arrowDown />
</button>
{isOpen && (
<div className="ml-8 mt-4 flex flex-col gap-1">
{languagesItems?.map(({ label, value: languageKey }, index) => {
const isActive = languageKey === lang
return (
<Link
className={cn(
"py-2 uppercase",
isActive
? "font-medium text-anakiwa-500"
: "font-normal text-white"
)}
href={`/${languageKey}`}
key={index}
>
{label}
</Link>
)
})}
</div>
)}
</div>
)
}
export function SiteHeaderMobile({ lang }: LangProps["params"]) {
const [header, setHeader] = useState(false)
const { t } = useTranslation(lang, "common")
@@ -88,6 +136,8 @@ export function SiteHeaderMobile({ lang }: LangProps["params"]) {
{t("menu.jobs")}
<Icons.externalUrl className="w-6" fill="white" />
</NextLink>
<LanguageSwitcher lang={lang} />
</div>
<div className="flex h-full w-full flex-col items-center justify-end gap-5 py-[40px] text-sm">
<div className="flex gap-5">
@@ -125,7 +175,7 @@ export function SiteHeaderMobile({ lang }: LangProps["params"]) {
<h1>{t("footer.privacyPolicy")}</h1>
<h1>{t("footer.termsOfUse")}</h1>
</div>
<h1 className="text-gray-400 text-center">
<h1 className="text-center text-gray-400">
{t("lastUpdatedAt", {
date: "January 16, 2024",
})}

View File

@@ -1,36 +1,49 @@
"use client"
import { siteConfig } from "@/config/site"
import { useAppSettings } from "@/hooks/useAppSettings"
import { MainNav, MainNavProps } from "@/components/main-nav"
import { useTranslation } from "@/app/i18n/client"
import { LocaleTypes } from "@/app/i18n/settings"
import { MainNav } from "@/components/main-nav"
import {
LanguageMapping,
LocaleTypes,
languagesItems,
} from "@/app/i18n/settings"
import { Icons } from "./icons"
import { SiteHeaderMobile } from "./site-header-mobile"
import { Dropdown } from "./ui/dropdown"
type SiteHeaderProps = {
lang: LocaleTypes
}
export function SiteHeader({ lang }: SiteHeaderProps) {
const { t: i18n } = useTranslation(lang, "common")
const { MAIN_NAV } = useAppSettings(lang)
return (
<header className="sticky top-0 z-40 w-full bg-white px-6 shadow-sm xl:px-20">
<div className="flex h-16 justify-between space-x-4 sm:space-x-0">
<MainNav items={MAIN_NAV} />
<div className="flex h-16 items-center justify-between space-x-4 sm:space-x-0">
<MainNav items={MAIN_NAV} lang={lang} />
<SiteHeaderMobile lang={lang} />
<div className="hidden flex-1 items-center justify-end space-x-4 md:flex">
<button type="button" className="flex gap-2">
<Icons.globe size={22} />
<span>
{i18n("menu.languages", {
locale: lang?.toUpperCase(),
})}
</span>
</button>
</div>
{siteConfig?.showLanguageSwitcher && (
<div className="hidden outline-none md:block">
<Dropdown
label={
<div className="flex items-center gap-1">
<Icons.globe size={22} />
<span className="!text-base !font-normal text-tuatara-950">
{LanguageMapping[lang] ?? LanguageMapping["en"]}
</span>
</div>
}
defaultItem={lang}
items={languagesItems}
onChange={(lang) => {
window?.location?.replace(`/${lang}`)
}}
/>
</div>
)}
</div>
</header>
)

View File

@@ -11,7 +11,7 @@ interface DropdownItemProps {
}
interface DropdownProps {
label: string
label: React.ReactNode
items?: DropdownItemProps[]
defaultItem?: string | number
onChange?: (value: DropdownItemProps["value"]) => void
@@ -53,7 +53,7 @@ const Dropdown = ({
<DropdownMenu.Portal>
<DropdownMenu.Content
className="max-h-[250px] min-w-[136px] overflow-scroll rounded-md border border-tuatara-200 bg-white py-2"
className="z-[50] max-h-[250px] min-w-[136px] overflow-scroll rounded-md border border-tuatara-200 bg-white py-2"
sideOffset={5}
>
{items?.map((item, index) => {

View File

@@ -1,6 +1,7 @@
export type SiteConfig = typeof siteConfig
1
export const siteConfig = {
showLanguageSwitcher: false, // TODO: enable when we have more languages
name: "Privacy & Scaling Explorations",
description:
"Enhancing Ethereum through cryptographic research and collective experimentation.",

View File

@@ -14,9 +14,13 @@ import { dslWorkingGroup } from "./projects/dsl-working-group"
import { ECIPHalo2 } from "./projects/ecip-halo2"
import { eigenTrust } from "./projects/eigen-trust"
import { Interep } from "./projects/interep"
import { jubmoji } from "./projects/jubmoji"
import { maci } from "./projects/maci"
import { nfctap } from "./projects/nfctap"
import { p0tion } from "./projects/p0tion"
import { p256 } from "./projects/p256"
import { pollenLabs } from "./projects/pollen-labs"
import { PerpetualPowersOfTau } from './projects/powers-of-tau'
import { PerpetualPowersOfTau } from "./projects/powers-of-tau"
import { pseSecurity } from "./projects/pse-security"
import { rln } from "./projects/rln"
import { semaphore } from "./projects/semaphore"
@@ -25,15 +29,13 @@ import { tlsn } from "./projects/tlsn"
import { trustedSetups } from "./projects/trusted-setups"
import { unirepProtocol } from "./projects/unirep-protocol"
import { wax } from "./projects/wax"
import { ZKKit } from "./projects/zk-kit"
import { zk3 } from "./projects/zk3"
import { ZKKit } from "./projects/zk-kit"
import { zkevmCommunity } from "./projects/zkevm-community"
import { zkitter } from "./projects/zkitter"
import { zkml } from "./projects/zkml"
import { Zkopru } from "./projects/zkopru"
import { zkp2p } from "./projects/zkp2p"
import { p256 } from "./projects/p256"
import { p0tion } from "./projects/p0tion"
export const ProjectLinkIconMap: ProjectLinkType = {
github: GithubIcon,
@@ -74,6 +76,8 @@ export const projects: ProjectInterface[] = [
ZKKit,
p256,
p0tion,
jubmoji,
nfctap,
/**
* Grant projects hidden until we have grant tag
zkp2p,

33
data/projects/jubmoji.ts Normal file
View File

@@ -0,0 +1,33 @@
import { ProjectInterface } from "@/lib/types"
const description = `
Jubmoji.quest is a place to keep personal, provable digital mementos from people you meet and places you visit IRL. Each time you tap a card, you collect a Jubmoji, a unique cryptographic signature that you can store privately and share as you wish!
`
export const jubmoji: ProjectInterface = {
id: "jubmoji",
projectStatus: "active",
image: "",
name: "jubmoji.quest",
tldr: "Users of Jubmoji.quest tap NFC cards to collect signatures. By collecting these signatures, they complete quests.",
description,
links: {
github: "https://github.com/jubmoji/jubmoji.quest",
website: "https://www.jubmoji.quest/",
},
tags: {
keywords: [
"anonymity/privacy",
"education",
"data portability",
"social",
"wallets",
"identity",
"key management",
"reputation",
"toolkits",
],
builtWith: ["snarkjs", "circom", "node"],
themes: ["build", "play"],
},
}

View File

@@ -7,7 +7,7 @@ Minimal Anti-Collusion Infrastructure (MACI) is a protocol designed to provide a
export const maci: ProjectInterface = {
id: "maci",
projectStatus: "active",
image: "maci.webp",
image: "maci.png",
name: "MACI",
tldr: "An on-chain voting solution that protects privacy and minimizes the risk of collusion and bribery",
description,

33
data/projects/nfctap.ts Normal file
View File

@@ -0,0 +1,33 @@
import { ProjectInterface } from "@/lib/types"
const description = `
NFC activations at SBC and FtC residency
`
export const nfctap: ProjectInterface = {
id: "nfctap",
projectStatus: "active",
image: "",
name: "nfctap.xyz",
tldr: "This project was built to activate NFCs at SBC and FtC and learn from it for a larger Devconnect experience with 200 cards and 5,000 attendees.",
description,
links: {
github: "https://github.com/jubmoji/nfctap.xyz",
website: "https://www.nfctap.xyz/",
},
tags: {
keywords: [
"anonymity/privacy",
"education",
"data portability",
"social",
"wallets",
"identity",
"key management",
"reputation",
"toolkits",
],
builtWith: ["snarkjs", "circom", "node"],
themes: ["build", "play"],
},
}

2533
package-lock.json generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB