diff --git a/app/[lang]/projects/page.tsx b/app/[lang]/projects/page.tsx index 1b448cf5..8d3efb0a 100644 --- a/app/[lang]/projects/page.tsx +++ b/app/[lang]/projects/page.tsx @@ -1,8 +1,9 @@ import { Suspense } from "react" import { Metadata } from "next" +import { AppContent } from "@/components/ui/app-content" +import { Label } from "@/components/ui/label" import { Divider } from "@/components/divider" -import { PageHeader } from "@/components/page-header" import ProjectFiltersBar from "@/components/project/project-filters-bar" import { ProjectList } from "@/components/project/project-list" import { ProjectResultBar } from "@/components/project/project-result-bar" @@ -19,22 +20,24 @@ export default async function ProjectsPage({ params: { lang } }: any) { return ( - +
+ + +
+ {t("subtitle")} +
+
+
+ + Loading...}> - +
+ + +
-
- -
-
- - -
-
+ +
) } diff --git a/app/i18n/locales/en/common.json b/app/i18n/locales/en/common.json index ee75f4b4..d3811396 100644 --- a/app/i18n/locales/en/common.json +++ b/app/i18n/locales/en/common.json @@ -88,8 +88,9 @@ "connectWithUsOnPlatform": "Connect with us on {{platform}}", "addResource": "Add a resource", "notCurrentlyActive": "Not Currently Active", + "inactive": "Inactive", "joinOurDiscord": "Join our discord", "prevBrandImage": "Previous branding", "editThisPage": "Edit this page", "contents": "Contents" -} \ No newline at end of file +} diff --git a/app/i18n/locales/en/projects-page.json b/app/i18n/locales/en/projects-page.json index a69f3232..3bb03676 100644 --- a/app/i18n/locales/en/projects-page.json +++ b/app/i18n/locales/en/projects-page.json @@ -1,4 +1,4 @@ { - "title": "Explore the library", - "subtitle": "PSE supports projects working on theoretical cryptography research, protocol development, open source tooling, experimental applications, and more." -} \ No newline at end of file + "title": "Explore our Project Library", + "subtitle": "Everything PSE works on is public and open source. All of our projects, whether research or development, are resources you can learn from and build with." +} diff --git a/components/project/project-card.tsx b/components/project/project-card.tsx index 1533af9e..1cc60dec 100644 --- a/components/project/project-card.tsx +++ b/components/project/project-card.tsx @@ -28,12 +28,23 @@ const TagsIconMapping: Record = { research: , } +const tagCardVariants = cva( + "text-xs font-sans text-tuatara-950 rounded-[3px] py-[2px] px-[6px]", + { + variants: { + variant: { + primary: "bg-[#D8FEA8]", + secondary: "bg-[#C2E8F5]", + }, + }, + } +) const projectCardVariants = cva( - "flex cursor-pointer flex-col overflow-hidden rounded-lg transition duration-150 ease-in hover:scale-105", + "flex cursor-pointer flex-col overflow-hidden rounded-lg transition duration-200 ease-in border border-transparent hover:border-anakiwa-500", { variants: { showLinks: { - true: "min-h-[450px]", + true: "min-h-[280px]", false: "min-h-[200px]", }, border: { @@ -54,14 +65,18 @@ export default function ProjectCard({ const { t } = useTranslation(lang, "common") const router = useRouter() - const { id, image, links, name, tags, imageAlt, projectStatus } = project + const { id, image, links, name, tags, imageAlt, projectStatus, cardTags } = + project ?? {} const projectNotActive = projectStatus !== "active" const { content: projectContent } = getProjectById(id, lang) return (
{ router.push(`/projects/${id}`) }} @@ -82,34 +97,52 @@ export default function ProjectCard({ )}
)} -
+
-

{name}

+

{name}

{projectContent?.tldr && ( -
-

{projectContent?.tldr}

+
+

+ {projectContent?.tldr} +

)}
-
- {showLinks && ( -
- {Object.entries(links ?? {})?.map(([website, url], index) => { - return ( - - ) - })} -
- )} +
{projectNotActive && ( - - {t("notCurrentlyActive")} + + {t("inactive")} )} +
+ {showLinks && ( +
+ {Object.entries(links ?? {})?.map(([website, url], index) => { + return ( + + ) + })} +
+ )} + {cardTags && ( +
+ {cardTags?.primary && ( +
+ {cardTags?.primary} +
+ )} + {cardTags?.secondary && ( +
+ {cardTags?.secondary} +
+ )} +
+ )} +
diff --git a/components/project/project-filters-bar.tsx b/components/project/project-filters-bar.tsx index bf1afba5..fd183ea0 100644 --- a/components/project/project-filters-bar.tsx +++ b/components/project/project-filters-bar.tsx @@ -49,7 +49,7 @@ const FilterWrapper = ({ label, children, className }: FilterWrapperProps) => { } export const ThemesButtonMapping = (lang: LocaleTypes): IThemesButton => { - const t = i18next.getFixedT(lang, "common") + const t = i18next.getFixedT(lang, "all") return { build: { @@ -128,8 +128,15 @@ export default function ProjectFiltersBar({ lang }: LangProps["params"]) { const [searchQuery, setSearchQuery] = useState("") const [filterCount, setFilterCount] = useState(0) - const { filters, toggleFilter, queryString, activeFilters, onFilterProject } = - useProjectFiltersState((state) => state) + const { + filters, + toggleFilter, + queryString, + activeFilters, + onFilterProject, + currentSection, + setCurrentSection, + } = useProjectFiltersState((state) => state) useEffect(() => { if (!queryString) return @@ -296,40 +303,73 @@ export default function ProjectFiltersBar({ lang }: LangProps["params"]) {
-
-
-
- ) => - setSearchQuery(e?.target?.value) - } - value={searchQuery} - placeholder={t("searchProjectPlaceholder")} - /> -
- - - - + ) + })} + + +
+
+
+ ) => + setSearchQuery(e?.target?.value) + } + value={searchQuery} + placeholder={t("searchProjectPlaceholder")} + /> +
+ + + + +
diff --git a/components/project/project-link.tsx b/components/project/project-link.tsx index be9243e1..1d65f7a3 100644 --- a/components/project/project-link.tsx +++ b/components/project/project-link.tsx @@ -24,6 +24,7 @@ export function ProjectLink({ website, url }: ProjectLinkProps) { }} target="_blank" rel="noopener noreferrer" + className="text-lg" > {icon} diff --git a/components/project/project-links.tsx b/components/project/project-links.tsx index e42547f5..b55a1238 100644 --- a/components/project/project-links.tsx +++ b/components/project/project-links.tsx @@ -3,9 +3,23 @@ import { RiTelegramLine as TelegramIcon } from "react-icons/ri" import { Icons } from "../icons" export const ProjectLinkIconMap: Record = { - github: , - website: , - twitter: , - telegram: , - discord: , + github: ( + + ), + website: ( + + ), + twitter: ( + + ), + telegram: ( + + ), + discord: ( + + ), } diff --git a/components/project/project-list.tsx b/components/project/project-list.tsx index 284860e7..d5377746 100644 --- a/components/project/project-list.tsx +++ b/components/project/project-list.tsx @@ -9,6 +9,7 @@ import { cva } from "class-variance-authority" import { LangProps } from "@/types/common" import { ProjectSection, + ProjectSectionDescriptionMapping, ProjectSectionLabelMapping, ProjectSections, } from "@/lib/types" @@ -46,7 +47,7 @@ export const ProjectList = ({ lang }: LangProps["params"]) => { const [isManualScroll, setIsManualScroll] = useState(false) const [isMounted, setIsMounted] = useState(false) - const { projects } = useProjectFiltersState((state) => state) + const { projects, currentSection } = useProjectFiltersState((state) => state) const noItems = projects?.length === 0 @@ -114,9 +115,9 @@ export const ProjectList = ({ lang }: LangProps["params"]) => { if (noItems) return return ( -
-
- {ProjectSections.map((section) => { +
+
+ {ProjectSections.map((section, index) => { const sectionProjects = projects.filter( (project) => @@ -127,9 +128,14 @@ export const ProjectList = ({ lang }: LangProps["params"]) => { const sectionTitle = ProjectSectionLabelMapping[section as ProjectSection] + const sectionDescription = + ProjectSectionDescriptionMapping[section as ProjectSection] + // todo: filter by project section if (!hasProjectsForSection) return null + const showTitle = ["archived"].includes(section) + return (
{
0 && currentSection == null + ? "pt-10" + : "" )} > -
-

{sectionTitle}

-
-
+ {showTitle && ( +
+

{sectionTitle}

+ + {sectionDescription} + +
+ )} +
{sectionProjects.map((project) => ( { })}
-