From d81bc0ea5a6345df5c689b7d8df30174ca60ac80 Mon Sep 17 00:00:00 2001 From: ragnep Date: Tue, 24 Feb 2026 09:42:54 +0200 Subject: [PATCH 1/3] set identity tab as default and contributors ratings count Signed-off-by: ragnep --- .../user/brain/UserPageBrainWrapper.test.tsx | 2 +- .../user/layout/UserPageTabs.test.tsx | 2 +- .../stats/UserPageHeaderStats.test.tsx | 2 +- .../ProfileRatersTableItem.test.tsx | 2 +- .../UserSetUpProfileCta.test.tsx | 2 +- __tests__/pages/userPageRep.test.tsx | 4 +- app/[user]/brain/page.tsx | 21 +++++ app/[user]/identity/page.tsx | 90 +++++++------------ app/[user]/page.tsx | 53 +++++++++-- .../NotificationIdentityRating.tsx | 2 +- components/common/OverlappingAvatars.tsx | 3 +- .../react-query-wrapper/ReactQueryWrapper.tsx | 2 +- .../user/brain/UserPageBrainWrapper.tsx | 2 +- components/user/layout/userTabs.config.ts | 14 +-- .../user/rep/header/TopRaterAvatars.tsx | 15 ++++ .../rep/new-rep/UserPageRepNewRepSearch.tsx | 2 +- .../name/UserPageHeaderName.tsx | 2 +- .../set-up-profile/UserSetUpProfileCta.tsx | 2 +- components/user/utils/stats/UserStatsRow.tsx | 4 +- 19 files changed, 137 insertions(+), 89 deletions(-) create mode 100644 app/[user]/brain/page.tsx diff --git a/__tests__/components/user/brain/UserPageBrainWrapper.test.tsx b/__tests__/components/user/brain/UserPageBrainWrapper.test.tsx index 31c9c43d0c..7507a52b11 100644 --- a/__tests__/components/user/brain/UserPageBrainWrapper.test.tsx +++ b/__tests__/components/user/brain/UserPageBrainWrapper.test.tsx @@ -52,7 +52,7 @@ describe("UserPageBrainWrapper", () => { }, identity: { id: "1" }, }); - expect(routerPush).toHaveBeenCalledWith("/alice/identity"); + expect(routerPush).toHaveBeenCalledWith("/alice"); }); it("shows drops when waves enabled", () => { diff --git a/__tests__/components/user/layout/UserPageTabs.test.tsx b/__tests__/components/user/layout/UserPageTabs.test.tsx index 215060112c..236ed861c0 100644 --- a/__tests__/components/user/layout/UserPageTabs.test.tsx +++ b/__tests__/components/user/layout/UserPageTabs.test.tsx @@ -38,7 +38,7 @@ const renderTabs = ( country: string = "US" ) => { (useRouter as jest.Mock).mockReturnValue({ push: jest.fn() }); - (usePathname as jest.Mock).mockReturnValue("/[user]/identity"); + (usePathname as jest.Mock).mockReturnValue("/[user]"); (useSearchParams as jest.Mock).mockReturnValue(new URLSearchParams()); (useParams as jest.Mock).mockReturnValue({ user: "testuser" }); capacitorMock.mockReturnValue({ isIos }); diff --git a/__tests__/components/user/user-page-header/stats/UserPageHeaderStats.test.tsx b/__tests__/components/user/user-page-header/stats/UserPageHeaderStats.test.tsx index fc96542ba9..2e2ac03497 100644 --- a/__tests__/components/user/user-page-header/stats/UserPageHeaderStats.test.tsx +++ b/__tests__/components/user/user-page-header/stats/UserPageHeaderStats.test.tsx @@ -28,7 +28,7 @@ describe('UserPageHeaderStats', () => { /> ); expect(screen.getByRole('link', { name: 'fmt-10 TDH' })).toHaveAttribute('href', '/bob/collected'); - expect(screen.getByRole('link', { name: 'fmt-20 Rep' })).toHaveAttribute('href', '/bob/identity'); + expect(screen.getByRole('link', { name: 'fmt-20 Rep' })).toHaveAttribute('href', '/bob'); expect(screen.getByRole('link', { name: 'fmt-3 TDH Rate' })).toHaveAttribute( 'href', '/bob/stats?activity=tdh-history' diff --git a/__tests__/components/user/utils/raters-table/ProfileRatersTableItem.test.tsx b/__tests__/components/user/utils/raters-table/ProfileRatersTableItem.test.tsx index 70e8bf0904..eed4c8e3e3 100644 --- a/__tests__/components/user/utils/raters-table/ProfileRatersTableItem.test.tsx +++ b/__tests__/components/user/utils/raters-table/ProfileRatersTableItem.test.tsx @@ -27,7 +27,7 @@ describe("ProfileRatersTableItem", () => { ); const link = screen.getByText("bob").closest("a")!; - expect(link).toHaveAttribute("href", "/bob/identity"); + expect(link).toHaveAttribute("href", "/bob"); expect(screen.getByText("+5")).toBeInTheDocument(); expect(cicProps.level).toBe(3); }); diff --git a/__tests__/components/user/utils/set-up-profile/UserSetUpProfileCta.test.tsx b/__tests__/components/user/utils/set-up-profile/UserSetUpProfileCta.test.tsx index d19d70099e..b0b3532776 100644 --- a/__tests__/components/user/utils/set-up-profile/UserSetUpProfileCta.test.tsx +++ b/__tests__/components/user/utils/set-up-profile/UserSetUpProfileCta.test.tsx @@ -22,7 +22,7 @@ describe('UserSetUpProfileCta', () => { useCtx.mockReturnValue({ address: '0xabc' }); renderWithProfile({ handle: null }); expect(screen.getByRole('button')).toBeInTheDocument(); - expect(screen.getByRole('link')).toHaveAttribute('href', '/0xabc/identity'); + expect(screen.getByRole('link')).toHaveAttribute('href', '/0xabc'); }); it('returns null when address missing or handle exists', () => { diff --git a/__tests__/pages/userPageRep.test.tsx b/__tests__/pages/userPageRep.test.tsx index d9f31a6cd7..da3737557e 100644 --- a/__tests__/pages/userPageRep.test.tsx +++ b/__tests__/pages/userPageRep.test.tsx @@ -52,7 +52,7 @@ function DummyRepTab({ profile }: { readonly profile: any }) { } const buildFactory = () => - createUserTabPage({ subroute: "identity", metaLabel: "Identity", Tab: DummyRepTab }); + createUserTabPage({ subroute: "", metaLabel: "Identity", Tab: DummyRepTab }); describe("rep page via createUserTabPage", () => { beforeEach(() => { @@ -79,7 +79,7 @@ describe("rep page via createUserTabPage", () => { expect(userPageNeedsRedirect).toHaveBeenCalledWith({ profile: expect.any(Object), req: { query: { user: "Alice", foo: "bar" } }, - subroute: "identity", + subroute: "", }); expect(redirectMock).not.toHaveBeenCalled(); }); diff --git a/app/[user]/brain/page.tsx b/app/[user]/brain/page.tsx new file mode 100644 index 0000000000..69903d7cb1 --- /dev/null +++ b/app/[user]/brain/page.tsx @@ -0,0 +1,21 @@ +import { createUserTabPage } from "@/app/[user]/_lib/userTabPageFactory"; +import UserPageBrainWrapper from "@/components/user/brain/UserPageBrainWrapper"; +import { + USER_PAGE_TAB_IDS, + USER_PAGE_TAB_MAP, +} from "@/components/user/layout/userTabs.config"; + +const TAB_CONFIG = USER_PAGE_TAB_MAP[USER_PAGE_TAB_IDS.BRAIN]; + +const { Page, generateMetadata } = createUserTabPage({ + subroute: TAB_CONFIG.route, + metaLabel: TAB_CONFIG.metaLabel, + Tab: ({ profile }) => ( +
+ +
+ ), +}); + +export default Page; +export { generateMetadata }; diff --git a/app/[user]/identity/page.tsx b/app/[user]/identity/page.tsx index e7a45f1563..1d7e3aa515 100644 --- a/app/[user]/identity/page.tsx +++ b/app/[user]/identity/page.tsx @@ -1,60 +1,32 @@ -import { createUserTabPage } from "@/app/[user]/_lib/userTabPageFactory"; -import type { ActivityLogParams } from "@/components/profile-activity/ProfileActivityLogs"; -import { - USER_PAGE_TAB_IDS, - USER_PAGE_TAB_MAP, -} from "@/components/user/layout/userTabs.config"; -import UserPageRepWrapper from "@/components/user/rep/UserPageRepWrapper"; -import type { ApiProfileRepRatesState } from "@/entities/IProfile"; -import type { ApiIdentity } from "@/generated/models/ApiIdentity"; -import { getProfileLogTypes } from "@/helpers/profile-logs.helpers"; -import { ProfileActivityFilterTargetType } from "@/types/enums"; - -export interface UserPageRepPropsRepRates { - readonly ratings: ApiProfileRepRatesState; - readonly rater: string | null; +import { redirect } from "next/navigation"; + +type PageProps = { + readonly params?: Promise<{ user: string }> | undefined; + readonly searchParams?: Promise> | undefined; +}; + +export default async function IdentityRedirectPage({ + params, + searchParams, +}: PageProps) { + const resolvedParams = params ? await params : undefined; + const user = resolvedParams?.user ?? ""; + const resolvedSearchParams = searchParams ? await searchParams : undefined; + + const query = new URLSearchParams(); + if (resolvedSearchParams) { + for (const [key, value] of Object.entries(resolvedSearchParams)) { + if (value === undefined) continue; + if (Array.isArray(value)) { + for (const v of value) { + query.append(key, v); + } + } else { + query.append(key, value); + } + } + } + + const qs = query.toString(); + redirect(`/${user}${qs ? `?${qs}` : ""}`); } - -const getInitialActivityLogParams = ( - handleOrWallet: string -): ActivityLogParams => ({ - page: 1, - pageSize: 10, - logTypes: getProfileLogTypes({ - logTypes: [], - }), - matter: null, - targetType: ProfileActivityFilterTargetType.ALL, - handleOrWallet, - groupId: null, -}); - -function RepTab({ profile }: { readonly profile: ApiIdentity }) { - const handleOrWallet = ( - profile.handle ?? - profile.wallets?.[0]?.wallet ?? - "" - ).toLowerCase(); - - const initialActivityLogParams = getInitialActivityLogParams(handleOrWallet); - - return ( -
- -
- ); -} - -const TAB_CONFIG = USER_PAGE_TAB_MAP[USER_PAGE_TAB_IDS.REP]; - -const { Page, generateMetadata } = createUserTabPage({ - subroute: TAB_CONFIG.route, - metaLabel: TAB_CONFIG.metaLabel, - Tab: RepTab, -}); - -export default Page; -export { generateMetadata }; diff --git a/app/[user]/page.tsx b/app/[user]/page.tsx index 69903d7cb1..e7a45f1563 100644 --- a/app/[user]/page.tsx +++ b/app/[user]/page.tsx @@ -1,20 +1,59 @@ import { createUserTabPage } from "@/app/[user]/_lib/userTabPageFactory"; -import UserPageBrainWrapper from "@/components/user/brain/UserPageBrainWrapper"; +import type { ActivityLogParams } from "@/components/profile-activity/ProfileActivityLogs"; import { USER_PAGE_TAB_IDS, USER_PAGE_TAB_MAP, } from "@/components/user/layout/userTabs.config"; +import UserPageRepWrapper from "@/components/user/rep/UserPageRepWrapper"; +import type { ApiProfileRepRatesState } from "@/entities/IProfile"; +import type { ApiIdentity } from "@/generated/models/ApiIdentity"; +import { getProfileLogTypes } from "@/helpers/profile-logs.helpers"; +import { ProfileActivityFilterTargetType } from "@/types/enums"; -const TAB_CONFIG = USER_PAGE_TAB_MAP[USER_PAGE_TAB_IDS.BRAIN]; +export interface UserPageRepPropsRepRates { + readonly ratings: ApiProfileRepRatesState; + readonly rater: string | null; +} + +const getInitialActivityLogParams = ( + handleOrWallet: string +): ActivityLogParams => ({ + page: 1, + pageSize: 10, + logTypes: getProfileLogTypes({ + logTypes: [], + }), + matter: null, + targetType: ProfileActivityFilterTargetType.ALL, + handleOrWallet, + groupId: null, +}); + +function RepTab({ profile }: { readonly profile: ApiIdentity }) { + const handleOrWallet = ( + profile.handle ?? + profile.wallets?.[0]?.wallet ?? + "" + ).toLowerCase(); + + const initialActivityLogParams = getInitialActivityLogParams(handleOrWallet); + + return ( +
+ +
+ ); +} + +const TAB_CONFIG = USER_PAGE_TAB_MAP[USER_PAGE_TAB_IDS.REP]; const { Page, generateMetadata } = createUserTabPage({ subroute: TAB_CONFIG.route, metaLabel: TAB_CONFIG.metaLabel, - Tab: ({ profile }) => ( -
- -
- ), + Tab: RepTab, }); export default Page; diff --git a/components/brain/notifications/identity-rating/NotificationIdentityRating.tsx b/components/brain/notifications/identity-rating/NotificationIdentityRating.tsx index 750f3dd26d..a5ddfec382 100644 --- a/components/brain/notifications/identity-rating/NotificationIdentityRating.tsx +++ b/components/brain/notifications/identity-rating/NotificationIdentityRating.tsx @@ -41,7 +41,7 @@ export default function NotificationIdentityRating({ const myHandle = connectedProfile?.handle; const getProfileLink = (): string | null => { if (!myHandle) return null; - return `/${myHandle}/identity`; + return `/${myHandle}`; }; const linkHref = getProfileLink(); diff --git a/components/common/OverlappingAvatars.tsx b/components/common/OverlappingAvatars.tsx index 9e4af2689d..1d61bb4afe 100644 --- a/components/common/OverlappingAvatars.tsx +++ b/components/common/OverlappingAvatars.tsx @@ -15,6 +15,7 @@ interface OverlappingAvatarItem { readonly ariaLabel?: string; readonly fallback?: string; readonly title?: string; + readonly tooltipContent?: React.ReactNode; } interface OverlappingAvatarsProps { @@ -116,7 +117,7 @@ export default function OverlappingAvatars({ delayShow={250} style={TOOLTIP_STYLES} > - {item.title} + {item.tooltipContent ?? item.title} ); diff --git a/components/react-query-wrapper/ReactQueryWrapper.tsx b/components/react-query-wrapper/ReactQueryWrapper.tsx index 4086e75832..e47ec37546 100644 --- a/components/react-query-wrapper/ReactQueryWrapper.tsx +++ b/components/react-query-wrapper/ReactQueryWrapper.tsx @@ -1,6 +1,6 @@ "use client"; -import type { UserPageRepPropsRepRates } from "@/app/[user]/identity/page"; +import type { UserPageRepPropsRepRates } from "@/app/[user]/page"; import type { ApiProfileRepRatesState, ProfileActivityLog, diff --git a/components/user/brain/UserPageBrainWrapper.tsx b/components/user/brain/UserPageBrainWrapper.tsx index f708f18155..8e724495ab 100644 --- a/components/user/brain/UserPageBrainWrapper.tsx +++ b/components/user/brain/UserPageBrainWrapper.tsx @@ -26,7 +26,7 @@ export default function UserPageBrainWrapper({ return; } if (connectedProfile || !address) { - router.push(`/${user}/identity`); + router.push(`/${user}`); } }, [connectedProfile, activeProfileProxy, address, showWaves]); diff --git a/components/user/layout/userTabs.config.ts b/components/user/layout/userTabs.config.ts index 397369a9c8..bdbe93ff87 100644 --- a/components/user/layout/userTabs.config.ts +++ b/components/user/layout/userTabs.config.ts @@ -17,15 +17,15 @@ type UserPageTabDefinition = { const TAB_DEFINITIONS = [ { - id: "brain", - title: "Brain", + id: "rep", + title: "Identity", route: "", - isVisible: ({ showWaves }: UserPageVisibilityContext) => showWaves, }, { - id: "rep", - title: "Identity", - route: "identity", + id: "brain", + title: "Brain", + route: "brain", + isVisible: ({ showWaves }: UserPageVisibilityContext) => showWaves, }, { id: "collected", @@ -102,7 +102,7 @@ export const USER_PAGE_TAB_IDS = USER_PAGE_TABS.reduce((acc, tab) => { return acc; }, {} as { [K in Uppercase]: UserPageTabKey }); -export const DEFAULT_USER_PAGE_TAB: UserPageTabKey = "collected"; +export const DEFAULT_USER_PAGE_TAB: UserPageTabKey = "rep"; export function getUserPageTabByRoute(route: string) { return USER_PAGE_TABS.find( diff --git a/components/user/rep/header/TopRaterAvatars.tsx b/components/user/rep/header/TopRaterAvatars.tsx index c28e746371..45310ef07b 100644 --- a/components/user/rep/header/TopRaterAvatars.tsx +++ b/components/user/rep/header/TopRaterAvatars.tsx @@ -8,6 +8,7 @@ import type { ApiIdentity } from "@/generated/models/ApiIdentity"; import type { Page } from "@/helpers/Types"; import OverlappingAvatars from "@/components/common/OverlappingAvatars"; import { RateMatter } from "@/types/enums"; +import { formatNumberWithCommas } from "@/helpers/Helpers"; import type { MouseEvent } from "react"; const STALE_TIME = 5 * 60 * 1000; @@ -66,6 +67,10 @@ export default function TopRaterAvatars({ const raterHandles = ratersPage?.data.map((r) => r.handle) ?? []; + const ratingByHandle = new Map( + ratersPage?.data.map((r) => [r.handle.toLowerCase(), r.rating]) ?? [] + ); + const identityQueries = useQueries({ queries: raterHandles.map((handle) => ({ queryKey: [QueryKey.PROFILE, handle.toLowerCase()], @@ -83,6 +88,15 @@ export default function TopRaterAvatars({ .map((q) => { const identity = q.data!; const target = identity.handle ?? identity.primary_wallet; + const rating = target + ? ratingByHandle.get(target.toLowerCase()) + : undefined; + const tooltipContent = + rating !== undefined ? ( + + {target} · {formatNumberWithCommas(rating)} + + ) : undefined; return { key: target, pfpUrl: identity.pfp ?? null, @@ -92,6 +106,7 @@ export default function TopRaterAvatars({ ? identity.handle.charAt(0).toUpperCase() : "?", title: target, + tooltipContent, }; }); diff --git a/components/user/rep/new-rep/UserPageRepNewRepSearch.tsx b/components/user/rep/new-rep/UserPageRepNewRepSearch.tsx index d488940fa2..2c413b2d92 100644 --- a/components/user/rep/new-rep/UserPageRepNewRepSearch.tsx +++ b/components/user/rep/new-rep/UserPageRepNewRepSearch.tsx @@ -270,7 +270,7 @@ export default function UserPageRepNewRepSearch({ className="tw-hidden lg:tw-block tw-text-xs tw-font-medium tw-text-iron-500"> Grant Rep -
+
Your available Rep: diff --git a/components/user/user-page-header/name/UserPageHeaderName.tsx b/components/user/user-page-header/name/UserPageHeaderName.tsx index d8fff0fdc2..222b2c3b08 100644 --- a/components/user/user-page-header/name/UserPageHeaderName.tsx +++ b/components/user/user-page-header/name/UserPageHeaderName.tsx @@ -65,7 +65,7 @@ export default function UserPageHeaderName({

{profile?.handle && ( -
+
)} diff --git a/components/user/utils/set-up-profile/UserSetUpProfileCta.tsx b/components/user/utils/set-up-profile/UserSetUpProfileCta.tsx index a5c1decae3..a9faacba02 100644 --- a/components/user/utils/set-up-profile/UserSetUpProfileCta.tsx +++ b/components/user/utils/set-up-profile/UserSetUpProfileCta.tsx @@ -19,7 +19,7 @@ export default function UserSetUpProfileCta() { return (
- + diff --git a/components/user/utils/stats/UserStatsRow.tsx b/components/user/utils/stats/UserStatsRow.tsx index 3688b8f5e4..c33a9ded32 100644 --- a/components/user/utils/stats/UserStatsRow.tsx +++ b/components/user/utils/stats/UserStatsRow.tsx @@ -100,7 +100,7 @@ export default function UserStatsRow({ @@ -112,7 +112,7 @@ export default function UserStatsRow({ From 674712e324d9a07e0f3b9241217cf11ce5db140d Mon Sep 17 00:00:00 2001 From: ragnep Date: Tue, 24 Feb 2026 09:53:32 +0200 Subject: [PATCH 2/3] fixed issues Signed-off-by: ragnep --- app/[user]/identity/page.tsx | 30 +++++++++---------- .../user/rep/header/TopRaterAvatars.tsx | 4 +-- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/app/[user]/identity/page.tsx b/app/[user]/identity/page.tsx index 1d7e3aa515..b56a7c0cc0 100644 --- a/app/[user]/identity/page.tsx +++ b/app/[user]/identity/page.tsx @@ -5,6 +5,17 @@ type PageProps = { readonly searchParams?: Promise> | undefined; }; +function buildQueryString( + params: Record +): string { + const query = new URLSearchParams(); + for (const [key, value] of Object.entries(params)) { + const values = Array.isArray(value) ? value : value !== undefined ? [value] : []; + values.forEach((v) => query.append(key, v)); + } + return query.toString(); +} + export default async function IdentityRedirectPage({ params, searchParams, @@ -13,20 +24,7 @@ export default async function IdentityRedirectPage({ const user = resolvedParams?.user ?? ""; const resolvedSearchParams = searchParams ? await searchParams : undefined; - const query = new URLSearchParams(); - if (resolvedSearchParams) { - for (const [key, value] of Object.entries(resolvedSearchParams)) { - if (value === undefined) continue; - if (Array.isArray(value)) { - for (const v of value) { - query.append(key, v); - } - } else { - query.append(key, value); - } - } - } - - const qs = query.toString(); - redirect(`/${user}${qs ? `?${qs}` : ""}`); + const qs = resolvedSearchParams ? buildQueryString(resolvedSearchParams) : ""; + const destination = qs ? `/${user}?${qs}` : `/${user}`; + redirect(destination); } diff --git a/components/user/rep/header/TopRaterAvatars.tsx b/components/user/rep/header/TopRaterAvatars.tsx index 45310ef07b..c1f5d4b822 100644 --- a/components/user/rep/header/TopRaterAvatars.tsx +++ b/components/user/rep/header/TopRaterAvatars.tsx @@ -92,11 +92,11 @@ export default function TopRaterAvatars({ ? ratingByHandle.get(target.toLowerCase()) : undefined; const tooltipContent = - rating !== undefined ? ( + rating === undefined ? undefined : ( {target} · {formatNumberWithCommas(rating)} - ) : undefined; + ); return { key: target, pfpUrl: identity.pfp ?? null, From 368d8f0aa12c314778492810b6545b62098b7c31 Mon Sep 17 00:00:00 2001 From: ragnep Date: Tue, 24 Feb 2026 10:02:28 +0200 Subject: [PATCH 3/3] fixed issues Signed-off-by: ragnep --- app/[user]/identity/page.tsx | 7 ++++--- components/common/OverlappingAvatars.tsx | 4 ++-- components/user/layout/userTabs.config.ts | 3 +-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/[user]/identity/page.tsx b/app/[user]/identity/page.tsx index b56a7c0cc0..81c7843397 100644 --- a/app/[user]/identity/page.tsx +++ b/app/[user]/identity/page.tsx @@ -1,4 +1,4 @@ -import { redirect } from "next/navigation"; +import { permanentRedirect } from "next/navigation"; type PageProps = { readonly params?: Promise<{ user: string }> | undefined; @@ -10,7 +10,8 @@ function buildQueryString( ): string { const query = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { - const values = Array.isArray(value) ? value : value !== undefined ? [value] : []; + if (value === undefined) continue; + const values = Array.isArray(value) ? value : [value]; values.forEach((v) => query.append(key, v)); } return query.toString(); @@ -26,5 +27,5 @@ export default async function IdentityRedirectPage({ const qs = resolvedSearchParams ? buildQueryString(resolvedSearchParams) : ""; const destination = qs ? `/${user}?${qs}` : `/${user}`; - redirect(destination); + permanentRedirect(destination); } diff --git a/components/common/OverlappingAvatars.tsx b/components/common/OverlappingAvatars.tsx index 1d61bb4afe..63003fb60c 100644 --- a/components/common/OverlappingAvatars.tsx +++ b/components/common/OverlappingAvatars.tsx @@ -4,7 +4,7 @@ import { getScaledImageUri, ImageScale } from "@/helpers/image.helpers"; import { TOOLTIP_STYLES } from "@/helpers/tooltip.helpers"; import useIsTouchDevice from "@/hooks/useIsTouchDevice"; import Link from "next/link"; -import type { MouseEvent } from "react"; +import type { MouseEvent, ReactNode } from "react"; import { useId } from "react"; import { Tooltip } from "react-tooltip"; @@ -15,7 +15,7 @@ interface OverlappingAvatarItem { readonly ariaLabel?: string; readonly fallback?: string; readonly title?: string; - readonly tooltipContent?: React.ReactNode; + readonly tooltipContent?: ReactNode; } interface OverlappingAvatarsProps { diff --git a/components/user/layout/userTabs.config.ts b/components/user/layout/userTabs.config.ts index bdbe93ff87..574df22cbd 100644 --- a/components/user/layout/userTabs.config.ts +++ b/components/user/layout/userTabs.config.ts @@ -11,7 +11,6 @@ type UserPageTabDefinition = { readonly badge?: string | undefined; readonly isVisible?: | ((context: UserPageVisibilityContext) => boolean) - | undefined | undefined; }; @@ -27,7 +26,7 @@ const TAB_DEFINITIONS = [ route: "brain", isVisible: ({ showWaves }: UserPageVisibilityContext) => showWaves, }, -{ + { id: "collected", title: "Collected", route: "collected",