diff --git a/components/sections/ConnectWithUs.tsx b/components/sections/ConnectWithUs.tsx
new file mode 100644
index 00000000..ca8e3cb3
--- /dev/null
+++ b/components/sections/ConnectWithUs.tsx
@@ -0,0 +1,64 @@
+import Image from "next/image"
+import Link from "next/link"
+
+import { useTranslation } from "@/app/i18n/client"
+import { LocaleTypes } from "@/app/i18n/settings"
+
+import { Card } from "../cards/card"
+import { Icons } from "../icons"
+import { AppContent } from "../ui/app-content"
+import { Button } from "../ui/button"
+
+interface ConnectWithUsProps {
+ lang: LocaleTypes
+}
+
+const ConnectWithUs = ({ lang }: ConnectWithUsProps) => {
+ const { t } = useTranslation(lang, "homepage")
+ const { t: common } = useTranslation(lang, "common")
+
+ return (
+
+
+
+ {common("ourYearProgram", {
+ year: new Date().getFullYear(),
+ })}
+
+
+
+
+
+
+ {t("connectWithUs.title")}
+
+
{t("connectWithUs.description")}
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+ConnectWithUs.displayName = "ConnectWithUs"
+
+export { ConnectWithUs }
diff --git a/components/site-footer.tsx b/components/site-footer.tsx
index b02a3d84..1a8148a6 100644
--- a/components/site-footer.tsx
+++ b/components/site-footer.tsx
@@ -2,11 +2,11 @@
import Image from "next/image"
import Link from "next/link"
-import PSELogo from "@/public/logos/pse-logo-circle.svg"
import { LangProps } from "@/types/common"
import { NavItem } from "@/types/nav"
import { siteConfig } from "@/config/site"
+import { cn } from "@/lib/utils"
import { useAppSettings } from "@/hooks/useAppSettings"
import { useTranslation } from "@/app/i18n/client"
@@ -35,8 +35,14 @@ const ItemLabel = ({
)
}
-const LinksWrapper = ({ children }: { children: React.ReactNode }) => {
- return
{children}
+const LinksWrapper = ({
+ children,
+ className,
+}: {
+ children: React.ReactNode
+ className?: string
+}) => {
+ return
{children}
}
export function SiteFooter({ lang }: LangProps["params"]) {
diff --git a/components/site-header-mobile.tsx b/components/site-header-mobile.tsx
index 685f70b2..49b36919 100644
--- a/components/site-header-mobile.tsx
+++ b/components/site-header-mobile.tsx
@@ -75,6 +75,8 @@ export function SiteHeaderMobile({ lang }: LangProps["params"]) {
const [header, setHeader] = useState(false)
const { t } = useTranslation(lang, "common")
+ const { MAIN_NAV } = useAppSettings(lang)
+
return (
-
-
setHeader(false)}
- className="border-y-2 border-white p-[16px] uppercase"
- >
- {t("menu.home")}
-
-
setHeader(false)}
- href={`/${lang}/projects`}
- className="border-b-2 border-white p-[16px] pt-0 uppercase"
- >
- {t("menu.projectLibrary")}
-
-
setHeader(false)}
- href={`/${lang}/about`}
- className="border-b-2 border-white p-[16px] pt-0 uppercase"
- >
- {t("menu.about")}
-
-
setHeader(false)}
- href={`/${lang}/resources`}
- className="border-b-2 border-white p-[16px] pt-0 uppercase"
- >
- {t("menu.resources")}
-
-
- {t("menu.jobs")}
-
-
+
+ {MAIN_NAV.map((item, index) => {
+ if (item.onlyFooter) return null
-
+ return (
+
setHeader(false)}
+ className="border-b-2 border-white p-4 uppercase"
+ >
+ {item.title}
+
+ )
+ })}
+
+
+
diff --git a/components/ui/accordion.tsx b/components/ui/accordion.tsx
index f1dc7338..4fd56d13 100644
--- a/components/ui/accordion.tsx
+++ b/components/ui/accordion.tsx
@@ -1,53 +1,104 @@
"use client"
-import React from "react"
+import React, { ReactNode } from "react"
import * as RadixAccordion from "@radix-ui/react-accordion"
+import { cn } from "@/lib/utils"
+
import { Icons } from "../icons"
interface AccordionItemProps {
- label: string
+ label: ReactNode
children?: React.ReactNode
value: string
}
+type AccordionPadding = "xs" | "sm"
+
interface AccordionProps extends RadixAccordion.AccordionImplProps {
- type: "single" | "multiple"
+ type?: "single" | "multiple"
+ size?: AccordionPadding
defaultValue?: string
items: AccordionItemProps[]
+ className?: string
+ iconOnHover?: boolean
+ id?: string
+}
+
+const AccordionSizeMapping: Record
= {
+ xs: "pt-4",
+ sm: "py-6",
}
const Accordion = ({
type = "multiple",
+ id,
defaultValue,
items,
+ size = "sm",
+ className,
+ iconOnHover = true,
}: AccordionProps) => {
+ const groupName = id ? `group/${id}` : "group"
+
return (
{items?.map(({ label, children, value }, accordionIndex) => (
-
-
- {label}
-
+
-
-
-
-
+ {typeof label === "string" ? (
+
+ {label}
+
+ ) : (
+ label
+ )}
+
+
+
+
-
+
{children}
diff --git a/components/ui/dropdown.tsx b/components/ui/dropdown.tsx
index b0ff5018..f129caea 100644
--- a/components/ui/dropdown.tsx
+++ b/components/ui/dropdown.tsx
@@ -10,12 +10,14 @@ interface DropdownItemProps {
value?: string | number
}
-interface DropdownProps {
+export interface DropdownProps {
label: React.ReactNode
items?: DropdownItemProps[]
defaultItem?: string | number
onChange?: (value: DropdownItemProps["value"]) => void
disabled?: boolean
+ className?: string
+ width?: number
}
const Dropdown = ({
@@ -24,6 +26,8 @@ const Dropdown = ({
defaultItem,
disabled,
items,
+ className,
+ width,
}: DropdownProps) => {
const [selected, setSelected] =
useState(defaultItem)
@@ -33,27 +37,37 @@ const Dropdown = ({
if (typeof onChange === "function") onChange(value)
}
+ const selectedLabel = items?.find((item) => item.value === selected)?.label
+
return (
{items?.map((item, index) => {
diff --git a/config/site.ts b/config/site.ts
index 3f2a0e07..8ab6c51d 100644
--- a/config/site.ts
+++ b/config/site.ts
@@ -22,6 +22,10 @@ export const siteConfig = {
firstGoodIssue: "https://pse-gfis.vercel.app",
discordAnnouncementChannel:
"https://discord.com/channels/943612659163602974/969614451089227876",
+ acceleratorProgram:
+ "https://github.com/privacy-scaling-explorations/acceleration-program/issues/new?assignees=&labels=&projects=&template=propose-your-open-task.md&title=",
+ coreProgram:
+ "https://docs.google.com/forms/d/e/1FAIpQLSendzYY0z_z7fZ37g3jmydvzS9I7OWKbY2JrqAnyNqeaBHvMQ/viewform",
},
addGithubResource:
"https://github.com/privacy-scaling-explorations/website-v2/blob/main/app/%5Blang%5D/content/resources.md",
diff --git a/data/programs/acceleratorProgramFaq.tsx b/data/programs/acceleratorProgramFaq.tsx
new file mode 100644
index 00000000..c739d29c
--- /dev/null
+++ b/data/programs/acceleratorProgramFaq.tsx
@@ -0,0 +1,51 @@
+import { Faq } from "@/lib/types"
+
+export const acceleratorProgramFaq: Faq[] = [
+ {
+ question: "Who can apply?",
+ answer:
+ "The Accelerator program is open to alumni of our entry level programs (e.g. Launch Program, ZK Playground) and other applicants at beginner to intermediate levels with programmable cryptography.",
+ },
+ {
+ question: "What platform does the program use?",
+ answer:
+ "We will primarily utilize a Github repository for managing documents and staging of the grant proposals, grantees, and their progress. Stakeholders involved can utilize Github issues and pull requests to comment and collaborate.",
+ },
+ {
+ question: "How does the grant funding work?",
+ answer: (
+ <>
+
+ While the core funding this program comes through PSE via the Ethereum
+ Ecosystem Support Program (ESP), some bounties are supported by
+ specific teams.
+
+
+ Selected grantees will receive a small amount of funding after the
+ completion of the first milestone. Following milestones will be
+ awarded larger amounts.
+
+ >
+ ),
+ },
+ {
+ question: "How many proposals are accepted per open task?",
+ answer:
+ "Generally one proposal will be accepted. However, it is possible for applicants to form a team and work collaboratively.",
+ },
+ {
+ question: "How long will I have to tackle the open tasks?",
+ answer:
+ "Though our rounds are run in three month periods, the duration of your grant may be shorter or longer depending on task details.",
+ },
+ {
+ question: "Can I propose an open task?",
+ answer:
+ "If you have an interesting idea, you can submit it as an self proposed open task. Just to make sure you clearly credit to the original idea and clearly state if that idea is also funded by someone else.",
+ },
+ {
+ question: "What if I have more questions?",
+ answer:
+ "For any further questions or additional information, you can join our Telegram group!",
+ },
+]
diff --git a/data/programs/coreProgramFaq.tsx b/data/programs/coreProgramFaq.tsx
new file mode 100644
index 00000000..1ad82599
--- /dev/null
+++ b/data/programs/coreProgramFaq.tsx
@@ -0,0 +1,34 @@
+import { Faq } from "@/lib/types"
+
+export const coreProgramFaq: Faq[] = [
+ {
+ question: "Who can apply?",
+ answer:
+ "The Core Program is open to university students based in Japan, South Korea, Taiwan, Costa Rica, Ecuador and Argentina with a basic understanding of programming. If you're currently enrolled in a mathematics or computer science program, you're likely an excellent fit.",
+ },
+ {
+ question: "What is the structure of the program?",
+ answer:
+ "We use a hybrid learning model with the majority of learning happening online and weekly in-person meetings for discussions and problem-solving. The program consists of three stages: 1) self-driven exploration & guidance, 2) hands-on circuit writing, and 3) open-source project contribution.",
+ },
+ {
+ question: "How much time will I need to commit?",
+ answer:
+ "We're looking for dedicated students who can commit 40 hours a week from mid-July to September. You will be required to attend in-person meetups once a week and make presentations.",
+ },
+ {
+ question: "Can I participate remotely?",
+ answer:
+ "Unfortunately no, the weekly in-person sessions are required for in-depth discussions and collaborative problem-solving.",
+ },
+ {
+ question: "What will I gain from this program?",
+ answer:
+ "Upon completing the program, you'll have comprehensive knowledge about programmable cryptography, a bolstered GitHub portfolio, and opportunities to apply for grants for further research and contributions.",
+ },
+ {
+ question: "What if I have more questions?",
+ answer:
+ "For any further questions or additional information, you can join our Telegram group!",
+ },
+]
diff --git a/hooks/useAppSettings.ts b/hooks/useAppSettings.ts
index 0199f9df..f01abfdd 100644
--- a/hooks/useAppSettings.ts
+++ b/hooks/useAppSettings.ts
@@ -15,11 +15,16 @@ export function useAppSettings(lang: LocaleTypes) {
{
title: t("menu.home"),
href: "/",
+ onlyMobile: true,
},
{
title: t("menu.projectLibrary"),
href: "/projects",
},
+ {
+ title: t("menu.programs"),
+ href: "/programs",
+ },
{
title: t("menu.about"),
href: "/about",
diff --git a/lib/types.ts b/lib/types.ts
index 9a599f8a..5b510cc5 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -1,7 +1,14 @@
+import { ReactNode } from "react"
+
// list of project groups
export const ProjectSections = ["pse", "grant", "collaboration"] as const
export type ProjectSection = (typeof ProjectSections)[number]
+export interface Faq {
+ question: string
+ answer: ReactNode
+}
+
export const ProjectStatusList = ["active", "inactive"] as const
export type ProjectStatusType = (typeof ProjectStatusList)[number]
diff --git a/public/images/programs-3.png b/public/images/programs-3.png
new file mode 100644
index 00000000..f5d99c39
Binary files /dev/null and b/public/images/programs-3.png differ
diff --git a/public/programs-page-banner.png b/public/programs-page-banner.png
new file mode 100644
index 00000000..12a38f10
Binary files /dev/null and b/public/programs-page-banner.png differ
diff --git a/styles/globals.css b/styles/globals.css
index 1e6a14d5..7aa5d193 100644
--- a/styles/globals.css
+++ b/styles/globals.css
@@ -121,3 +121,39 @@
.link {
@apply border-b-2 border-transparent duration-200 ease-in-out hover:border-orange;
}
+
+
+#howToApply a {
+ @apply underline;
+}
+
+/*Accordion open state*/
+.accordion > [data-state="open"] [data-icon="minus"] {
+ @apply block;
+}
+.accordion > [data-state="open"] [data-icon="plus"] {
+ @apply hidden;
+}
+
+/*Accordion close state*/
+.accordion > [data-state="closed"] [data-icon="plus"] {
+ @apply block;
+}
+.accordion > [data-state="closed"] [data-icon="minus"] {
+ @apply hidden;
+}
+
+/*Accordion hover state content*/
+.accordion.hover-icon > [data-state="closed"] [data-icon="plus"] {
+ @apply hidden;
+}
+.accordion.hover-icon > [data-state="closed"]:hover [data-icon="plus"] {
+ @apply block;
+}
+
+/*Accordion hover state content*/
+@media screen and (max-width: 768px) {
+ .accordion.hover-icon > [data-state="closed"] [data-icon="plus"] {
+ @apply block;
+ }
+}
diff --git a/tailwind.config.js b/tailwind.config.js
index 2f39b141..20d1d3a3 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -135,3 +135,4 @@ module.exports = {
},
plugins: [require("tailwindcss-animate")],
}
+
diff --git a/types/nav.ts b/types/nav.ts
index 8492a7f2..ee57eca3 100644
--- a/types/nav.ts
+++ b/types/nav.ts
@@ -5,4 +5,5 @@ export interface NavItem {
external?: boolean
onlyFooter?: boolean
onlyHeader?: boolean
+ onlyMobile?: boolean
}