-
- {`Showing ${projects?.length} projects with:`}{" "}
-
-
- {Object.entries(activeFilters).map(([key, filters], index) => {
- return (
- <>
- {filters?.map((filter) => {
- if (filter?.length === 0) return null
-
- return (
-
- toggleFilter({
- tag: key as ProjectFilter,
- value: filter,
- })
- }
- key={`${index}-${filter}`}
- >
- {filter}
-
- )
- })}
- >
- )
- })}
+
+ {resultLabel}
+ sortProjectBy(sortBy as ProjectSortBy)}
+ disabled={!projects?.length}
+ />
+ {haveActiveFilters && (
+
+ {Object.entries(activeFilters).map(([key, filters], index) => {
+ return (
+ <>
+ {filters?.map((filter) => {
+ if (filter?.length === 0) return null
+
+ return (
+
+ toggleFilter({
+ tag: key as ProjectFilter,
+ value: filter,
+ })
+ }
+ key={`${index}-${filter}`}
+ >
+ {filter}
+
+ )
+ })}
+ >
+ )
+ })}
+
+ )}
)
}
diff --git a/components/ui/button.tsx b/components/ui/button.tsx
index 57ecf84..1ee0b5f 100644
--- a/components/ui/button.tsx
+++ b/components/ui/button.tsx
@@ -6,7 +6,7 @@ import { LucideIcon } from "lucide-react"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
- "inline-flex items-center justify-center duration-100 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
+ "font-sans inline-flex items-center justify-center duration-100 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
{
variants: {
variant: {
diff --git a/components/ui/dropdown.tsx b/components/ui/dropdown.tsx
new file mode 100644
index 0000000..fce7dbd
--- /dev/null
+++ b/components/ui/dropdown.tsx
@@ -0,0 +1,87 @@
+import React, { useState } from "react"
+import * as DropdownMenu from "@radix-ui/react-dropdown-menu"
+
+import { cn } from "@/lib/utils"
+
+import { Icons } from "../icons"
+
+interface DropdownItemProps {
+ label: string
+ value?: string | number
+}
+
+interface DropdownProps {
+ label: string
+ items?: DropdownItemProps[]
+ defaultItem?: string | number
+ onChange?: (value: DropdownItemProps["value"]) => void
+ disabled?: boolean
+}
+
+const Dropdown = ({
+ label,
+ onChange,
+ defaultItem,
+ disabled,
+ items,
+}: DropdownProps) => {
+ const [selected, setSelected] =
+ useState
(defaultItem)
+
+ const onSelectCallback = ({ value }: DropdownItemProps) => {
+ setSelected(value)
+ if (typeof onChange === "function") onChange(value)
+ }
+
+ return (
+
+
+
+
+
+
+
+ {items?.map((item, index) => {
+ const active = selected === item.value
+ return (
+ onSelectCallback(item)}
+ >
+ {active && (
+
+ )}
+ {item.label}
+
+ )
+ })}
+
+
+
+ )
+}
+
+Dropdown.displayName = "Dropdown"
+export { Dropdown }
diff --git a/data/projects/anon-aadhaar.ts b/data/projects/anon-aadhaar.ts
index f39d558..d621b94 100644
--- a/data/projects/anon-aadhaar.ts
+++ b/data/projects/anon-aadhaar.ts
@@ -7,7 +7,7 @@ Anon Aadhaar is a project that allows individuals to prove their citizenship ano
export const anonAadhaar: ProjectInterface = {
id: "anon-aadhaar",
projectStatus: "active",
- image: "",
+ image: "anon-aadhaar.svg",
name: "Anon Aadhaar",
tldr: "Tools for building build privacy-preserving applications using government ID cards, specifically Aadhaar cards in India.",
description,
@@ -17,7 +17,7 @@ export const anonAadhaar: ProjectInterface = {
tags: {
keywords: ["Anonymity/privacy", "Social", "Identity", "Voting/governance"],
themes: ["build", "play"],
- type: ["Legos/dev tools", "Lego sets/toolkits", "Proof of concept"],
+ types: ["Legos/dev tools", "Lego sets/toolkits", "Proof of concept"],
builtWith: ["circom", "rsa"],
},
}
diff --git a/data/projects/anon-klub.ts b/data/projects/anon-klub.ts
index 2d98868..0e192c5 100644
--- a/data/projects/anon-klub.ts
+++ b/data/projects/anon-klub.ts
@@ -24,7 +24,7 @@ export const anonKlub: ProjectInterface = {
"Voting/governance",
],
themes: ["build", "play"],
- type: ["Infrastructure/protocol", "Prototype", "Proof of concept"],
+ types: ["Infrastructure/protocol", "Prototype", "Proof of concept"],
builtWith: ["circom", "snarkjs", "halo2"],
},
}
diff --git a/data/projects/bandada.ts b/data/projects/bandada.ts
index 7452f79..c5f4122 100644
--- a/data/projects/bandada.ts
+++ b/data/projects/bandada.ts
@@ -27,7 +27,7 @@ export const bandada: ProjectInterface = {
"Scaling",
"Key management",
],
- type: [
+ types: [
"Legos/dev tools",
"Lego sets/toolkits",
"Prototype",
diff --git a/data/projects/channel-4.ts b/data/projects/channel-4.ts
index 20fce33..121f9de 100644
--- a/data/projects/channel-4.ts
+++ b/data/projects/channel-4.ts
@@ -19,7 +19,7 @@ export const channel4: ProjectInterface = {
tags: {
keywords: ["Scaling"],
themes: ["play"],
- type: ["Application"],
+ types: ["Application"],
builtWith: ["state channel", "smart contract"],
},
}
diff --git a/data/projects/dsl-working-group.ts b/data/projects/dsl-working-group.ts
index cc28ba2..1728b3e 100644
--- a/data/projects/dsl-working-group.ts
+++ b/data/projects/dsl-working-group.ts
@@ -15,7 +15,7 @@ export const dslWorkingGroup: ProjectInterface = {
github: "https://github.com/privacy-scaling-explorations/chiquito/",
},
tags: {
- type: ["Legos/dev tools", "Proof of concept", "Developer tooling"],
+ types: ["Legos/dev tools", "Proof of concept", "Developer tooling"],
keywords: [],
themes: ["research"],
builtWith: [],
diff --git a/data/projects/eigen-trust.ts b/data/projects/eigen-trust.ts
index edbe216..d39187e 100644
--- a/data/projects/eigen-trust.ts
+++ b/data/projects/eigen-trust.ts
@@ -17,7 +17,7 @@ export const eigenTrust: ProjectInterface = {
tags: {
keywords: ["Reputation", "Identity"],
themes: ["build"],
- type: ["Infrastructure/protocol"],
+ types: ["Infrastructure/protocol"],
builtWith: ["ethereum attestation service", "halo2", "ethers.rs"],
},
}
diff --git a/data/projects/pollen-labs.ts b/data/projects/pollen-labs.ts
index a2ffbea..60816ae 100644
--- a/data/projects/pollen-labs.ts
+++ b/data/projects/pollen-labs.ts
@@ -18,7 +18,7 @@ export const pollenLabs: ProjectInterface = {
tags: {
keywords: ["Anonymity/privacy", "Scaling"],
themes: ["play"],
- type: ["Application"],
+ types: ["Application"],
builtWith: [],
},
}
diff --git a/data/projects/rln.ts b/data/projects/rln.ts
index 80beecf..7fe248b 100644
--- a/data/projects/rln.ts
+++ b/data/projects/rln.ts
@@ -7,7 +7,7 @@ Rate-Limiting Nullifier (RLN) is a protocol designed to combat spam and denial o
export const rln: ProjectInterface = {
id: "rln",
projectStatus: "active",
- image: "rln.webp",
+ image: "rln.svg",
name: "Rate-Limiting Nullifier",
tldr: "A protocol for deterring spam and maintaining anonymity in communication systems.",
description,
diff --git a/data/projects/summa.ts b/data/projects/summa.ts
index 6071b03..a1dbdea 100644
--- a/data/projects/summa.ts
+++ b/data/projects/summa.ts
@@ -17,7 +17,7 @@ export const summa: ProjectInterface = {
tags: {
keywords: ["Anonymity/privacy", "Computational Integrity"],
themes: ["build", "play"],
- type: ["Infrastructure/protocol", "Application"],
+ types: ["Infrastructure/protocol", "Application"],
builtWith: ["halo2"],
},
}
diff --git a/data/projects/tlsn.ts b/data/projects/tlsn.ts
index e7dc2b8..fbe14b2 100644
--- a/data/projects/tlsn.ts
+++ b/data/projects/tlsn.ts
@@ -18,7 +18,7 @@ export const tlsn: ProjectInterface = {
},
tags: {
themes: ["build"],
- type: [],
+ types: [],
builtWith: [],
keywords: [],
},
diff --git a/data/projects/trusted-setups.ts b/data/projects/trusted-setups.ts
index 9560cf3..e08b792 100644
--- a/data/projects/trusted-setups.ts
+++ b/data/projects/trusted-setups.ts
@@ -15,7 +15,7 @@ export const trustedSetups: ProjectInterface = {
},
tags: {
themes: ["play"],
- type: ["Legos/dev tools", "Lego sets/toolkits"],
+ types: ["Legos/dev tools", "Lego sets/toolkits"],
builtWith: [],
keywords: ["Scaling", "Education"],
},
diff --git a/data/projects/unirep-protocol.ts b/data/projects/unirep-protocol.ts
index 1496ced..12299dd 100644
--- a/data/projects/unirep-protocol.ts
+++ b/data/projects/unirep-protocol.ts
@@ -20,7 +20,7 @@ export const unirepProtocol: ProjectInterface = {
tags: {
keywords: ["Anonymity/privacy", "Social", "Identity", "Reputation"],
themes: ["build"],
- type: ["Legos/dev tools, Protocol"],
+ types: ["Legos/dev tools, Protocol"],
builtWith: ["semaphore", "circom"],
},
}
diff --git a/data/projects/zk3.ts b/data/projects/zk3.ts
index 7950a27..1b4feb5 100644
--- a/data/projects/zk3.ts
+++ b/data/projects/zk3.ts
@@ -18,7 +18,7 @@ export const zk3: ProjectInterface = {
},
tags: {
themes: ["play"],
- type: [
+ types: [
"Legos/dev tools",
"Lego sets/toolkits",
"Infrastructure/protocol",
diff --git a/data/projects/zkml.ts b/data/projects/zkml.ts
index a40396d..6c7e43b 100644
--- a/data/projects/zkml.ts
+++ b/data/projects/zkml.ts
@@ -17,7 +17,7 @@ export const zkml: ProjectInterface = {
tags: {
keywords: ["Anonymity/privacy", "Scaling"],
themes: ["research"],
- type: ["Proof of concept", "Infrastructure/protocol"],
+ types: ["Proof of concept", "Infrastructure/protocol"],
builtWith: ["circom", "halo2", "nova"],
},
}
diff --git a/data/projects/zkp2p.ts b/data/projects/zkp2p.ts
index 2deffc1..12d5a56 100644
--- a/data/projects/zkp2p.ts
+++ b/data/projects/zkp2p.ts
@@ -18,8 +18,8 @@ export const zkp2p: ProjectInterface = {
},
tags: {
keywords: ["Private communications"],
- theme: ["play"],
- type: ["Proof of concept", "Application"],
+ themes: ["play"],
+ types: ["Proof of concept", "Application"],
builtWith: ["circom", "halo2"],
},
}
diff --git a/lib/types.ts b/lib/types.ts
index 4763ac6..9069ab5 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -19,6 +19,8 @@ export type ProjectLinkWebsite =
export type ProjectLinkType = Partial>
export type ProjectExtraLinkType = "buildWith" | "play" | "research" | "learn"
+export type TagType = "types" | "themes" | "builtWith" | "keywords"
+export type ProjectTags = Partial>
export type ActionLinkTypeLink = {
label: string
url: string
@@ -36,6 +38,6 @@ export interface ProjectInterface {
description: string
links?: ProjectLinkType
projectStatus: ProjectStatusType
- tags?: Record
+ tags?: ProjectTags
extraLinks?: ActionLinkType
}
diff --git a/package.json b/package.json
index d555424..dd4d8d3 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.4",
+ "@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.4.0",
"clsx": "^1.2.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 441631f..66318bb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,6 +14,9 @@ dependencies:
'@radix-ui/react-dialog':
specifier: ^1.0.4
version: 1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-dropdown-menu':
+ specifier: ^2.0.5
+ version: 2.0.5(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-slot':
specifier: ^1.0.2
version: 1.0.2(@types/react@18.2.7)(react@18.2.0)
@@ -360,6 +363,34 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
+ /@floating-ui/core@1.4.1:
+ resolution: {integrity: sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==}
+ dependencies:
+ '@floating-ui/utils': 0.1.1
+ dev: false
+
+ /@floating-ui/dom@1.5.1:
+ resolution: {integrity: sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==}
+ dependencies:
+ '@floating-ui/core': 1.4.1
+ '@floating-ui/utils': 0.1.1
+ dev: false
+
+ /@floating-ui/react-dom@2.0.2(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+ dependencies:
+ '@floating-ui/dom': 1.5.1
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@floating-ui/utils@0.1.1:
+ resolution: {integrity: sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==}
+ dev: false
+
/@humanwhocodes/config-array@0.11.8:
resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==}
engines: {node: '>=10.10.0'}
@@ -574,6 +605,35 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
+ /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.3
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collapsible': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@types/react': 18.2.7
+ '@types/react-dom': 18.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==}
peerDependencies:
@@ -755,6 +815,33 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
+ /@radix-ui/react-dropdown-menu@2.0.5(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-xdOrZzOTocqqkCkYo8yRPCib5OkTkqN7lqNCdxwPOdE466DOaNl4N8PkUIlsXthQvW5Wwkd+aEmWpfWlBoDPEw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.3
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-menu': 2.0.5(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@types/react': 18.2.7
+ '@types/react-dom': 18.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.7)(react@18.2.0):
resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
peerDependencies:
@@ -807,6 +894,74 @@ packages:
react: 18.2.0
dev: false
+ /@radix-ui/react-menu@2.0.5(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-Gw4f9pwdH+w5w+49k0gLjN0PfRDHvxmAgG16AbyJZ7zhwZ6PBHKtWohvnSwfusfnK3L68dpBREHpVkj8wEM7ZA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.3
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@types/react': 18.2.7
+ '@types/react-dom': 18.2.4
+ aria-hidden: 1.2.3
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ react-remove-scroll: 2.5.5(@types/react@18.2.7)(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-popper@1.1.2(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.3
+ '@floating-ui/react-dom': 2.0.2(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/rect': 1.0.1
+ '@types/react': 18.2.7
+ '@types/react-dom': 18.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-portal@1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==}
peerDependencies:
@@ -871,6 +1026,35 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
+ /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.3
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.2.7)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.7)(react@18.2.0)
+ '@types/react': 18.2.7
+ '@types/react-dom': 18.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-slot@1.0.2(@types/react@18.2.7)(react@18.2.0):
resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
peerDependencies:
@@ -958,6 +1142,21 @@ packages:
react: 18.2.0
dev: false
+ /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.7)(react@18.2.0):
+ resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.3
+ '@radix-ui/rect': 1.0.1
+ '@types/react': 18.2.7
+ react: 18.2.0
+ dev: false
+
/@radix-ui/react-use-size@1.0.1(@types/react@18.2.7)(react@18.2.0):
resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==}
peerDependencies:
@@ -973,6 +1172,12 @@ packages:
react: 18.2.0
dev: false
+ /@radix-ui/rect@1.0.1:
+ resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
+ dependencies:
+ '@babel/runtime': 7.22.3
+ dev: false
+
/@rushstack/eslint-patch@1.3.0:
resolution: {integrity: sha512-IthPJsJR85GhOkp3Hvp8zFOPK5ynKn6STyHa/WZpioK7E1aYDiBzpqQPrngc14DszIUkIrdd3k9Iu0XSzlP/1w==}
dev: true
diff --git a/public/icons/404-search.svg b/public/icons/404-search.svg
new file mode 100644
index 0000000..cd5f8fd
--- /dev/null
+++ b/public/icons/404-search.svg
@@ -0,0 +1,9 @@
+
diff --git a/public/project-banners/anon-aadhaar.svg b/public/project-banners/anon-aadhaar.svg
new file mode 100644
index 0000000..63244af
--- /dev/null
+++ b/public/project-banners/anon-aadhaar.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/project-banners/discreetly.svg b/public/project-banners/discreetly.svg
index ab5727b..449beaf 100644
--- a/public/project-banners/discreetly.svg
+++ b/public/project-banners/discreetly.svg
@@ -1,4 +1,13 @@
-