From cbfabc114bc09c4563020bd16221fdf1dc607c3e Mon Sep 17 00:00:00 2001 From: Theodore Abitbol Date: Fri, 26 Sep 2025 14:00:06 +0200 Subject: [PATCH 1/8] feat: add 3D interactive BadgeCard with foreground icons Closes #64 --- frontend/public/badge_bug_hunter.svg | 1 + frontend/public/badge_community.svg | 1 + frontend/public/badge_documentation.svg | 1 + frontend/public/badge_open_source.svg | 1 + frontend/public/badge_smart_contract.svg | 1 + frontend/src/components/badges/BadgesList.tsx | 33 ++++++ frontend/src/components/ui/BadgeCard.tsx | 106 ++++++++++++++++++ frontend/src/components/ui/card.tsx | 52 ++++++++- 8 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 frontend/public/badge_bug_hunter.svg create mode 100644 frontend/public/badge_community.svg create mode 100644 frontend/public/badge_documentation.svg create mode 100644 frontend/public/badge_open_source.svg create mode 100644 frontend/public/badge_smart_contract.svg create mode 100644 frontend/src/components/ui/BadgeCard.tsx diff --git a/frontend/public/badge_bug_hunter.svg b/frontend/public/badge_bug_hunter.svg new file mode 100644 index 0000000..ad2173c --- /dev/null +++ b/frontend/public/badge_bug_hunter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/badge_community.svg b/frontend/public/badge_community.svg new file mode 100644 index 0000000..bba3a56 --- /dev/null +++ b/frontend/public/badge_community.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/badge_documentation.svg b/frontend/public/badge_documentation.svg new file mode 100644 index 0000000..f1739c6 --- /dev/null +++ b/frontend/public/badge_documentation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/badge_open_source.svg b/frontend/public/badge_open_source.svg new file mode 100644 index 0000000..1bcba58 --- /dev/null +++ b/frontend/public/badge_open_source.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/badge_smart_contract.svg b/frontend/public/badge_smart_contract.svg new file mode 100644 index 0000000..1cb5fea --- /dev/null +++ b/frontend/public/badge_smart_contract.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index cd3a7cf..6fcbd3f 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -1,5 +1,6 @@ import React, { useMemo, useState } from "react"; import { BadgeCheck } from "lucide-react"; +import { BadgeCard } from "@/components/ui/BadgeCard"; import { Card, @@ -17,6 +18,14 @@ import { Input } from "../ui/input"; import { AiOutlineLoading3Quarters } from "react-icons/ai"; import ErrorDisplay from "@/components/displayError/index"; +const badgeIcons = [ + "/badge_bug_hunter.svg", + "/badge_community.svg", + "/badge_documentation.svg", + "/badge_smart_contract.svg", + "/badge_open_source.svg", +]; + export function BadgesList(): React.ReactElement { const { data, isLoading, error } = useGetBadges(); const [searchQuery, setSearchQuery] = useState(""); @@ -57,6 +66,7 @@ export function BadgesList(): React.ReactElement { +<<<<<<< HEAD
{filtered.map((badge) => ( @@ -76,6 +86,29 @@ export function BadgesList(): React.ReactElement { )} +======= +
+ {filtered.map((badge, index) => ( + + } + > + + {badge.name} + {badge.description} + + + + ))} +
+ +>>>>>>> d9140a0 (feat: add 3D interactive BadgeCard with foreground icons) ); } diff --git a/frontend/src/components/ui/BadgeCard.tsx b/frontend/src/components/ui/BadgeCard.tsx new file mode 100644 index 0000000..d8d878b --- /dev/null +++ b/frontend/src/components/ui/BadgeCard.tsx @@ -0,0 +1,106 @@ +import React, { useRef } from "react"; +import { cn } from "@/lib/utils"; +import { Card } from "@/components/ui/card"; + +interface BadgeCardProps { + children: React.ReactNode; + className?: string; + foregroundIcon?: React.ReactNode; // NEW optional prop +} + +export function BadgeCard({ + children, + className, + foregroundIcon, +}: BadgeCardProps) { + const tiltRef = useRef(null); + const contentRef = useRef(null); + const iconRef = useRef(null); + + const onEnter = () => { + if (!tiltRef.current || !contentRef.current) return; + tiltRef.current.style.transition = "transform 200ms ease-out"; + contentRef.current.style.transition = "transform 200ms ease-out"; + if (iconRef.current) + iconRef.current.style.transition = "transform 200ms ease-out"; + + tiltRef.current.style.transform = "rotateX(0deg) rotateY(0deg)"; + contentRef.current.style.transform = "translateZ(30px)"; + if (iconRef.current) iconRef.current.style.transform = "translateZ(180px)"; + }; + + const onMove = (e: React.MouseEvent) => { + if (!tiltRef.current || !contentRef.current) return; + const rect = tiltRef.current.getBoundingClientRect(); + const x = (e.clientX - rect.left) / rect.width - 0.5; + const y = (e.clientY - rect.top) / rect.height - 0.5; + const rotateX = y * -12; + const rotateY = x * 12; + + tiltRef.current.style.transition = "transform 120ms ease-out"; + contentRef.current.style.transition = "transform 120ms ease-out"; + if (iconRef.current) + iconRef.current.style.transition = "transform 120ms ease-out"; + + tiltRef.current.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; + contentRef.current.style.transform = `translateZ(30px) translate(${x * 8}px, ${y * 8}px)`; + if (iconRef.current) { + iconRef.current.style.transform = `translateZ(60px) translate(${x * 12}px, ${y * 12}px)`; + } + }; + + const onLeave = () => { + if (!tiltRef.current || !contentRef.current) return; + tiltRef.current.style.transition = "transform 350ms ease-out"; + contentRef.current.style.transition = "transform 350ms ease-out"; + if (iconRef.current) + iconRef.current.style.transition = "transform 350ms ease-out"; + + tiltRef.current.style.transform = "rotateX(0deg) rotateY(0deg)"; + contentRef.current.style.transform = "translateZ(0px)"; + if (iconRef.current) iconRef.current.style.transform = "translateZ(0px)"; + }; + + return ( +
+
+ + {" "} + {foregroundIcon && ( +
+ {foregroundIcon} +
+ )} +
+ {children} +
+
+
+
+ ); +} diff --git a/frontend/src/components/ui/card.tsx b/frontend/src/components/ui/card.tsx index 93a82d9..3b247e7 100644 --- a/frontend/src/components/ui/card.tsx +++ b/frontend/src/components/ui/card.tsx @@ -1,20 +1,64 @@ import * as React from "react"; - import { cn } from "@/lib/utils"; -function Card({ className, ...props }: React.ComponentProps<"div">) { +interface CardProps extends React.ComponentProps<"div"> { + with3D?: boolean; + foregroundIcon?: React.ReactNode; +} + +function Card({ + className, + with3D = false, + foregroundIcon, + children, + ...props +}: CardProps) { + const ref = React.useRef(null); + + const handleMouseMove = (e: React.MouseEvent) => { + if (!with3D || !ref.current) return; + const rect = ref.current.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + const centerX = rect.width / 2; + const centerY = rect.height / 2; + const rotateX = ((y - centerY) / centerY) * -5; + const rotateY = ((x - centerX) / centerX) * 5; + + ref.current.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; + }; + + const handleMouseLeave = () => { + if (!with3D || !ref.current) return; + ref.current.style.transform = "rotateX(0deg) rotateY(0deg)"; + }; + return (
+ > +
+ {children} +
+ {with3D && foregroundIcon && ( +
+ {foregroundIcon} +
+ )} +
); } +// keep your existing slots the same function CardHeader({ className, ...props }: React.ComponentProps<"div">) { return (
Date: Fri, 26 Sep 2025 14:14:45 +0200 Subject: [PATCH 2/8] fix: fixed bg-card --- frontend/src/components/ui/card.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/ui/card.tsx b/frontend/src/components/ui/card.tsx index 3b247e7..1a89aed 100644 --- a/frontend/src/components/ui/card.tsx +++ b/frontend/src/components/ui/card.tsx @@ -40,7 +40,7 @@ function Card({ onMouseMove={handleMouseMove} onMouseLeave={handleMouseLeave} className={cn( - "backdrop-blur-sm text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm transition-transform duration-300 ease-out", + "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm transition-transform duration-300 ease-out", with3D ? "transform-style-3d perspective-[1000px]" : "", className )} From 3e736ce886dd21c60896ea3c8d3e7592db6bdfee Mon Sep 17 00:00:00 2001 From: Theodore Abitbol Date: Tue, 28 Oct 2025 23:31:45 +0100 Subject: [PATCH 3/8] refactored background svg into a different component --- frontend/src/components/AppWrapper.tsx | 7 +- frontend/src/components/Background.tsx | 182 +++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/Background.tsx diff --git a/frontend/src/components/AppWrapper.tsx b/frontend/src/components/AppWrapper.tsx index 80a1421..9aa3b3a 100644 --- a/frontend/src/components/AppWrapper.tsx +++ b/frontend/src/components/AppWrapper.tsx @@ -1,9 +1,8 @@ import "@rainbow-me/rainbowkit/styles.css"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { WagmiProvider } from "wagmi"; -import { RainbowKitProvider } from "@rainbow-me/rainbowkit"; +import { RainbowKitProvider, ConnectButton } from "@rainbow-me/rainbowkit"; import { config } from "../lib/wagmi"; -import { ConnectButton } from "@rainbow-me/rainbowkit"; import { SidebarProvider, SidebarTrigger, @@ -11,7 +10,7 @@ import { } from "@/components/ui/sidebar"; import { AppSidebar } from "@/components/AppSidebar"; import { ActivityTokenBalance } from "@/components/ActivityTokenBalance"; -import { AppBackground } from "@/components/AppBackground"; +import { Background } from "@/components/Background"; const queryClient = new QueryClient(); @@ -25,7 +24,7 @@ export function AppWrapper({ children }: AppWrapperProps) {
- + diff --git a/frontend/src/components/Background.tsx b/frontend/src/components/Background.tsx new file mode 100644 index 0000000..c9e3bca --- /dev/null +++ b/frontend/src/components/Background.tsx @@ -0,0 +1,182 @@ +// components/Background.tsx +export function Background() { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +} From bc736b1300c6c01e0d0c11924ae3b7f5525cb1ac Mon Sep 17 00:00:00 2001 From: Theodore Abitbol Date: Tue, 28 Oct 2025 23:34:26 +0100 Subject: [PATCH 4/8] simplified badges --- frontend/src/components/badges/BadgesList.tsx | 57 +++++-------------- 1 file changed, 15 insertions(+), 42 deletions(-) diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index 6fcbd3f..ec81004 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -1,7 +1,7 @@ import React, { useMemo, useState } from "react"; -import { BadgeCheck } from "lucide-react"; -import { BadgeCard } from "@/components/ui/BadgeCard"; +import { Search } from "lucide-react"; +import { BadgeCard } from "@/components/ui/BadgeCard"; import { Card, CardContent, @@ -12,19 +12,12 @@ import { import { useGetBadges } from "@/hooks/badges/use-get-badges"; import { HARD_CODED_BADGES } from "@/lib/constants/badgeConstants"; import type { Badge } from "@/lib/types/badges"; -import { Search } from "lucide-react"; import { CreateBadgeButton } from "@/components/badges/CreateBadgeButton"; import { Input } from "../ui/input"; import { AiOutlineLoading3Quarters } from "react-icons/ai"; import ErrorDisplay from "@/components/displayError/index"; -const badgeIcons = [ - "/badge_bug_hunter.svg", - "/badge_community.svg", - "/badge_documentation.svg", - "/badge_smart_contract.svg", - "/badge_open_source.svg", -]; +const BUG_HUNTER_ICON = "/badge_smart_contract.svg"; export function BadgesList(): React.ReactElement { const { data, isLoading, error } = useGetBadges(); @@ -66,49 +59,29 @@ export function BadgesList(): React.ReactElement {
-<<<<<<< HEAD
{filtered.map((badge) => ( - + + } + > - -
- - {badge.name} -
-
+ {badge.name} {badge.description}
-
+ ))}
)} -======= -
- {filtered.map((badge, index) => ( - - } - > - - {badge.name} - {badge.description} - - - - ))} -
- ->>>>>>> d9140a0 (feat: add 3D interactive BadgeCard with foreground icons) ); } From 442a2bc0617763d6c8d6c433539ef8a5b2daf831 Mon Sep 17 00:00:00 2001 From: "theodore.abitbol" Date: Wed, 29 Oct 2025 12:45:00 +0100 Subject: [PATCH 5/8] solved merge conflict --- frontend/.astro/types.d.ts | 1 - frontend/package-lock.json | 56 ++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/frontend/.astro/types.d.ts b/frontend/.astro/types.d.ts index 03d7cc4..f964fe0 100644 --- a/frontend/.astro/types.d.ts +++ b/frontend/.astro/types.d.ts @@ -1,2 +1 @@ /// -/// \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2078c1e..c6a83f0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -90,7 +90,8 @@ "version": "2.12.2", "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.12.2.tgz", "integrity": "sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@astrojs/internal-helpers": { "version": "0.7.2", @@ -299,6 +300,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -831,6 +833,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -854,6 +857,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -3069,6 +3073,7 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", "license": "MIT", + "peer": true, "dependencies": { "node-fetch": "^2.7.0" } @@ -3122,6 +3127,7 @@ "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", "license": "MIT", + "peer": true, "engines": { "node": "^14.21.3 || >=16" }, @@ -4644,6 +4650,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -4999,6 +5006,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -5306,6 +5314,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -6261,6 +6270,7 @@ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.87.4.tgz", "integrity": "sha512-T5GT/1ZaNsUXf5I3RhcYuT17I4CPlbZgyLxc/ZGv7ciS6esytlbjb3DgUFO6c8JWYMDpdjSWInyGZUErgzqhcA==", "license": "MIT", + "peer": true, "dependencies": { "@tanstack/query-core": "5.87.4" }, @@ -6442,8 +6452,7 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -6593,6 +6602,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz", "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.10.0" } @@ -6611,6 +6621,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -6620,6 +6631,7 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.9.tgz", "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.0.0" } @@ -6702,6 +6714,7 @@ "integrity": "sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.43.0", "@typescript-eslint/types": "8.43.0", @@ -6912,6 +6925,7 @@ "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.17.3.tgz", "integrity": "sha512-jHivr1UPoJTX5Uel4AZSOwrCf4mO42LcdmnhJtUxZaRWhW4FviFbIfs0moAWWld7GOT+2XnuVZjjA/K32uUnMQ==", "license": "MIT", + "peer": true, "dependencies": { "@emotion/hash": "^0.9.0", "@vanilla-extract/private": "^1.0.8", @@ -7120,6 +7134,7 @@ "resolved": "https://registry.npmjs.org/@wagmi/core/-/core-2.20.3.tgz", "integrity": "sha512-gsbuHnWxf0AYZISvR8LvF/vUCIq6/ZwT5f5/FKd6wLA7Wq05NihCvmQpIgrcVbpSJPL67wb6S8fXm3eJGJA1vQ==", "license": "MIT", + "peer": true, "dependencies": { "eventemitter3": "5.0.1", "mipd": "0.0.7", @@ -7693,6 +7708,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -7766,6 +7782,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -7930,7 +7947,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -8026,6 +8042,7 @@ "resolved": "https://registry.npmjs.org/astro/-/astro-5.14.1.tgz", "integrity": "sha512-gPa8NY7/lP8j8g81iy8UwANF3+aukKRWS68IlthZQNgykpg80ne6lbHOp6FErYycxQ1TUhgEfkXVDQZAoJx8Bg==", "license": "MIT", + "peer": true, "dependencies": { "@astrojs/compiler": "^2.12.2", "@astrojs/internal-helpers": "0.7.3", @@ -8504,6 +8521,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", @@ -8597,6 +8615,7 @@ "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -9535,8 +9554,7 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/dotenv": { "version": "17.2.2", @@ -9590,6 +9608,7 @@ "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.15.tgz", "integrity": "sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==", "license": "MIT", + "peer": true, "dependencies": { "@ecies/ciphers": "^0.2.3", "@noble/ciphers": "^1.3.0", @@ -9904,6 +9923,7 @@ "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -10605,7 +10625,8 @@ "version": "6.4.9", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/eventemitter3": { "version": "5.0.1", @@ -12525,6 +12546,7 @@ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", "license": "MIT", + "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -12565,6 +12587,7 @@ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -12746,6 +12769,7 @@ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", "license": "MPL-2.0", + "peer": true, "dependencies": { "detect-libc": "^2.0.3" }, @@ -13126,7 +13150,6 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -15201,7 +15224,6 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -15418,6 +15440,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -15427,6 +15450,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -15439,6 +15463,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz", "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -15464,8 +15489,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/react-refresh": { "version": "0.17.0", @@ -15588,6 +15612,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -16175,6 +16200,7 @@ "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz", "integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" } @@ -16414,6 +16440,7 @@ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", "license": "MIT", + "peer": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", @@ -17715,6 +17742,7 @@ "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -17755,6 +17783,7 @@ "resolved": "https://registry.npmjs.org/valtio/-/valtio-1.13.2.tgz", "integrity": "sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==", "license": "MIT", + "peer": true, "dependencies": { "derive-valtio": "0.1.0", "proxy-compare": "2.6.0", @@ -17838,6 +17867,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", @@ -17862,6 +17892,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz", "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -18064,6 +18095,7 @@ "resolved": "https://registry.npmjs.org/wagmi/-/wagmi-2.16.9.tgz", "integrity": "sha512-5NbjvuNNhT0t0lQsDD5otQqZ5RZBM1UhInHoBq/Lpnr6xLLa8AWxYqHg5oZtGCdiUNltys11iBOS6z4mLepIqw==", "license": "MIT", + "peer": true, "dependencies": { "@wagmi/connectors": "5.9.9", "@wagmi/core": "2.20.3", @@ -18296,6 +18328,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -18596,6 +18629,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } From 92deec2ddeee88bed0dd857fc8aa8bc461aad3b8 Mon Sep 17 00:00:00 2001 From: "theodore.abitbol" Date: Wed, 29 Oct 2025 15:44:53 +0100 Subject: [PATCH 6/8] implemented reviewers comments --- frontend/src/components/badges/BadgesList.tsx | 12 +++++++++--- frontend/src/components/ui/card.tsx | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index ec81004..40c57a8 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -17,7 +17,13 @@ import { Input } from "../ui/input"; import { AiOutlineLoading3Quarters } from "react-icons/ai"; import ErrorDisplay from "@/components/displayError/index"; -const BUG_HUNTER_ICON = "/badge_smart_contract.svg"; +const ICONS: Record = { + "Bug Hunter": "/badge_bug_hunter.svg", + Community: "/badge_community.svg", + Documentation: "/badge_documentation.svg", + "Open Source": "/badge_open_source.svg", + "Smart Contract": "/badge_smart_contract.svg", +}; export function BadgesList(): React.ReactElement { const { data, isLoading, error } = useGetBadges(); @@ -65,8 +71,8 @@ export function BadgesList(): React.ReactElement { key={badge.id ?? badge.name} foregroundIcon={ Bug Hunter badge } diff --git a/frontend/src/components/ui/card.tsx b/frontend/src/components/ui/card.tsx index 1a89aed..842314d 100644 --- a/frontend/src/components/ui/card.tsx +++ b/frontend/src/components/ui/card.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { cn } from "@/lib/utils"; +// Customized ShadCn component, don't overwrite it interface CardProps extends React.ComponentProps<"div"> { with3D?: boolean; foregroundIcon?: React.ReactNode; From 3dd5a2684a0d1e22da53bf278a7e368f60524732 Mon Sep 17 00:00:00 2001 From: "theodore.abitbol" Date: Wed, 29 Oct 2025 15:48:17 +0100 Subject: [PATCH 7/8] implemented reviews comments --- frontend/src/components/badges/BadgesList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/badges/BadgesList.tsx b/frontend/src/components/badges/BadgesList.tsx index 40c57a8..6c86bb3 100644 --- a/frontend/src/components/badges/BadgesList.tsx +++ b/frontend/src/components/badges/BadgesList.tsx @@ -19,8 +19,8 @@ import ErrorDisplay from "@/components/displayError/index"; const ICONS: Record = { "Bug Hunter": "/badge_bug_hunter.svg", - Community: "/badge_community.svg", - Documentation: "/badge_documentation.svg", + "Community": "/badge_community.svg", + "Documentation": "/badge_documentation.svg", "Open Source": "/badge_open_source.svg", "Smart Contract": "/badge_smart_contract.svg", }; From 91730dbb1e404a93ed8d61e5d8de55606bdcf61a Mon Sep 17 00:00:00 2001 From: "theodore.abitbol" Date: Wed, 29 Oct 2025 16:48:23 +0100 Subject: [PATCH 8/8] added default badge --- frontend/public/badge_default.svg | 1 + frontend/src/components/AppBackground.tsx | 181 ---------------------- 2 files changed, 1 insertion(+), 181 deletions(-) create mode 100644 frontend/public/badge_default.svg delete mode 100644 frontend/src/components/AppBackground.tsx diff --git a/frontend/public/badge_default.svg b/frontend/public/badge_default.svg new file mode 100644 index 0000000..05cf760 --- /dev/null +++ b/frontend/public/badge_default.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/AppBackground.tsx b/frontend/src/components/AppBackground.tsx deleted file mode 100644 index 6f7747f..0000000 --- a/frontend/src/components/AppBackground.tsx +++ /dev/null @@ -1,181 +0,0 @@ -export function AppBackground() { - return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ); -}