feat(home): add global wallet navigation and branding#2227
feat(home): add global wallet navigation and branding#2227webguru-hypha wants to merge 2 commits into
Conversation
|
Warning Review limit reached
More reviews will be available in 50 minutes and 20 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughThis PR introduces a new My Wallet page and component, enabling users to view wallet assets, transaction history, and pending rewards in a tabbed interface. The layout is updated with translated navigation labels and menu items linking to the new wallet page on both mobile and desktop. ChangesMy Wallet Feature
Sequence DiagramsequenceDiagram
participant User
participant MyWalletTabs
participant useAuthentication
participant useMe
participant TabSections
User->>MyWalletTabs: render(lang)
MyWalletTabs->>useAuthentication: check if signed in
MyWalletTabs->>useMe: fetch person data
alt Not authenticated or missing slug
MyWalletTabs-->>User: show sign-in prompt
else Loading
MyWalletTabs-->>User: show Loading...
else Loaded and authenticated
MyWalletTabs->>TabSections: render UserAssetsSection, UserTransactionsSection, PendingRewardsSection
TabSections-->>User: render tabs with wallet content
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/app/`[lang]/my-wallet/page.tsx:
- Around line 9-19: The page heading is hardcoded; import getTranslations from
"next-intl/server" at the top, call it inside MyWalletPage with the locale from
props.params (e.g., const t = getTranslations(lang)), and replace the hardcoded
<h1> text with a translated key like t('myWallet.title'); keep
MyWalletTabs(lang={lang}) as-is and ensure the translation key exists in the
my-wallet namespace/messages.
In `@apps/web/src/app/layout.tsx`:
- Around line 179-182: The tNav('myWallet') call references a missing
translation key; add a "myWallet" entry under the "Navigation" namespace in each
locale file so tNav can resolve it: update packages/i18n/src/messages/en.json,
de.json, es.json, fr.json and pt.json to include "Navigation": { "myWallet":
"<appropriate translated string>" } (use the English text in en.json and correct
translations in the other files) so the navigation label renders correctly in
Layout (tNav usage).
In `@apps/web/src/components/connected-menu-top.tsx`:
- Around line 172-186: The MenuTop consumer is passing logoNode but MenuTopProps
and MenuTop implementation don't accept or render it, which causes no logo when
useReplacementLogoNode is true; update the MenuTop API by adding logoNode?:
ReactNode to the MenuTopProps type and modify the MenuTop component (the MenuTop
function/JSX) to conditionally render the provided logoNode in place of the
default <Logo> when logoNode exists (respecting existing logoHref / hrefTarget
behavior), ensuring prop names (logoNode, logoHref, hrefTarget) are used
consistently and exported in the MenuTop signature so the custom ecosystem logo
supplied by connected-menu-top.tsx will render.
- Around line 55-92: The two useSWR calls (for activeSpace and
organisationSpaces) duplicate the same inline fetch logic; extract a shared
generic fetcher function (e.g., apiJsonNoCacheFetcher<T>(url: string,
contextLabel?: string): Promise<T | null | T[]>) that sets Accept header, uses
cache: 'no-store', checks response.ok, logs a contextual warning (use the
contextLabel like '[ConnectedMenuTop] activeSpace' / '[ConnectedMenuTop]
organisationSpaces'), and returns the parsed JSON cast to T (or a safe default
like null or [] as appropriate). Replace the inline async fetchers in the useSWR
for activeSpace and organisationSpaces with calls to this shared fetcher,
preserving the return type casts and the same null/empty-array fallback
behavior.
- Around line 8-12: The import is failing because getRootSpace is not exported
from `@hypha-platform/epics`; remove getRootSpace from the named import (leave
getDhoSpaceSlugFromPathname and isSafeImageUrl) and either (a) add a local
utility function getRootSpace inside connected-menu-top.tsx with the same
behavior used by this component, or (b) import getRootSpace from the correct
module that actually exports it if one exists; then update all usages of
getRootSpace in this file to reference the new local helper or the corrected
import and run the build to verify the error is resolved.
In `@apps/web/src/components/my-wallet-tabs.tsx`:
- Around line 18-33: Replace all hardcoded user-facing strings in the
MyWalletTabs component with next-intl translation lookups using the provided
lang prop; specifically, import and call the translator (e.g., useTranslations
or intl) in MyWalletTabs and replace "Loading..." with t('loading') (or an
equivalent key), "Sign in to view your wallet." with t('signInToViewWallet'),
and the tab labels "Wallet", "Transactions", "Rewards" with t('tabs.wallet'),
t('tabs.transactions'), t('tabs.rewards') respectively; ensure keys are added to
the relevant locale files and keep the component's logic (isLoading,
isAuthenticated, person?.slug, activeTab, setActiveTab) unchanged while swapping
literal strings for t(...) calls.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0b9a0e4f-2c85-43b3-9cb8-162810f79250
📒 Files selected for processing (4)
apps/web/src/app/[lang]/my-wallet/page.tsxapps/web/src/app/layout.tsxapps/web/src/components/connected-menu-top.tsxapps/web/src/components/my-wallet-tabs.tsx
| export default async function MyWalletPage(props: PageProps) { | ||
| const { lang } = await props.params; | ||
|
|
||
| return ( | ||
| <Container className="flex w-full flex-col gap-4 py-4"> | ||
| <h1 className="text-7 font-semibold tracking-tight text-foreground"> | ||
| My Wallet | ||
| </h1> | ||
| <MyWalletTabs lang={lang} /> | ||
| </Container> | ||
| ); |
There was a problem hiding this comment.
Hardcoded "My Wallet" page heading — use getTranslations
The <h1> text is a hardcoded user-facing string. In a Server Component the fix uses getTranslations from next-intl/server.
✏️ Proposed fix
+import { getTranslations } from 'next-intl/server';
import { Locale } from '@hypha-platform/i18n';
import { Container } from '@hypha-platform/ui';
import { MyWalletTabs } from '@web/components/my-wallet-tabs';
type PageProps = {
params: Promise<{ lang: Locale }>;
};
export default async function MyWalletPage(props: PageProps) {
const { lang } = await props.params;
+ const t = await getTranslations('MyWallet');
return (
<Container className="flex w-full flex-col gap-4 py-4">
- <h1 className="text-7 font-semibold tracking-tight text-foreground">
- My Wallet
- </h1>
+ <h1 className="text-7 font-semibold tracking-tight text-foreground">
+ {t('pageTitle')}
+ </h1>
<MyWalletTabs lang={lang} />
</Container>
);
}As per coding guidelines: "next-intl integration for i18n (no hardcoded user-facing strings)".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export default async function MyWalletPage(props: PageProps) { | |
| const { lang } = await props.params; | |
| return ( | |
| <Container className="flex w-full flex-col gap-4 py-4"> | |
| <h1 className="text-7 font-semibold tracking-tight text-foreground"> | |
| My Wallet | |
| </h1> | |
| <MyWalletTabs lang={lang} /> | |
| </Container> | |
| ); | |
| import { getTranslations } from 'next-intl/server'; | |
| import { Locale } from '@hypha-platform/i18n'; | |
| import { Container } from '@hypha-platform/ui'; | |
| import { MyWalletTabs } from '@web/components/my-wallet-tabs'; | |
| type PageProps = { | |
| params: Promise<{ lang: Locale }>; | |
| }; | |
| export default async function MyWalletPage(props: PageProps) { | |
| const { lang } = await props.params; | |
| const t = await getTranslations('MyWallet'); | |
| return ( | |
| <Container className="flex w-full flex-col gap-4 py-4"> | |
| <h1 className="text-7 font-semibold tracking-tight text-foreground"> | |
| {t('pageTitle')} | |
| </h1> | |
| <MyWalletTabs lang={lang} /> | |
| </Container> | |
| ); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/app/`[lang]/my-wallet/page.tsx around lines 9 - 19, The page
heading is hardcoded; import getTranslations from "next-intl/server" at the top,
call it inside MyWalletPage with the locale from props.params (e.g., const t =
getTranslations(lang)), and replace the hardcoded <h1> text with a translated
key like t('myWallet.title'); keep MyWalletTabs(lang={lang}) as-is and ensure
the translation key exists in the my-wallet namespace/messages.
| { | ||
| label: tNav('myWallet'), | ||
| href: `/${locale}/my-wallet`, | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for 'myWallet' key in all Navigation translation files
rg -n '"myWallet"' --type jsonRepository: hypha-dao/hypha-web
Length of output: 45
🏁 Script executed:
# Find translation file locations
fd -e json -e ts -e tsx | grep -i -E '(i18n|intl|locale|translation|message|lang)' | head -20Repository: hypha-dao/hypha-web
Length of output: 843
🏁 Script executed:
# Check the structure of navigation-related translations
fd -type f \( -name '*nav*' -o -name '*menu*' \) | grep -E '\.(json|ts|tsx)$'Repository: hypha-dao/hypha-web
Length of output: 234
🏁 Script executed:
# Look for where tNav is defined and how translations are loaded
rg -n "tNav\s*=" --type typescript --type tsx -A 3Repository: hypha-dao/hypha-web
Length of output: 98
🏁 Script executed:
# Check for any reference to 'myWallet' in the codebase (case-insensitive)
rg -i "myWallet" --type json --type typescript --type tsx -C 2Repository: hypha-dao/hypha-web
Length of output: 98
🏁 Script executed:
# Search for myWallet in the translation JSON files
grep -r "myWallet" packages/i18n/src/messages/Repository: hypha-dao/hypha-web
Length of output: 45
🏁 Script executed:
# Check the English translation file structure
cat packages/i18n/src/messages/en.json | head -100Repository: hypha-dao/hypha-web
Length of output: 4253
🏁 Script executed:
# Check the navigation configuration
cat packages/i18n/src/navigation.tsRepository: hypha-dao/hypha-web
Length of output: 258
🏁 Script executed:
# Check if myWallet appears anywhere in the en.json file
grep -i "wallet" packages/i18n/src/messages/en.jsonRepository: hypha-dao/hypha-web
Length of output: 4175
🏁 Script executed:
# Get the complete Navigation section from en.json
jq '.Navigation' packages/i18n/src/messages/en.jsonRepository: hypha-dao/hypha-web
Length of output: 640
🏁 Script executed:
# Check if myWallet is defined elsewhere in the codebase
rg -i "myWallet" --type jsonRepository: hypha-dao/hypha-web
Length of output: 45
🏁 Script executed:
# Also check if the layout.tsx file actually exists and has the line we're checking
grep -n "myWallet" apps/web/src/app/layout.tsxRepository: hypha-dao/hypha-web
Length of output: 126
Add myWallet translation key to the Navigation namespace in all translation files
The tNav('myWallet') call at line 180 references a translation key that doesn't exist in packages/i18n/src/messages/{en,de,es,fr,pt}.json. This will either throw an error or fall back to displaying the raw key string. Add the translation key to the Navigation section of all locale files.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/app/layout.tsx` around lines 179 - 182, The tNav('myWallet')
call references a missing translation key; add a "myWallet" entry under the
"Navigation" namespace in each locale file so tNav can resolve it: update
packages/i18n/src/messages/en.json, de.json, es.json, fr.json and pt.json to
include "Navigation": { "myWallet": "<appropriate translated string>" } (use the
English text in en.json and correct translations in the other files) so the
navigation label renders correctly in Layout (tNav usage).
| const { data: activeSpace, isLoading: isLoadingActiveSpace } = | ||
| useSWR<Space | null>( | ||
| activeSpaceSlug ? `/api/v1/spaces/${activeSpaceSlug}` : null, | ||
| async (url: string) => { | ||
| const response = await fetch(url, { | ||
| headers: { Accept: 'application/json' }, | ||
| cache: 'no-store', | ||
| }); | ||
| if (!response.ok) { | ||
| console.warn('[ConnectedMenuTop] spaces fetch failed', { | ||
| status: response.status, | ||
| url, | ||
| }); | ||
| return null; | ||
| } | ||
| return (await response.json()) as Space; | ||
| }, | ||
| ); | ||
| const { | ||
| data: organisationSpaces = [], | ||
| isLoading: isLoadingOrganisationSpaces, | ||
| } = useSWR<Space[]>( | ||
| activeSpaceSlug ? `/api/v1/spaces/${activeSpaceSlug}/organisation` : null, | ||
| async (url: string) => { | ||
| const response = await fetch(url, { | ||
| headers: { Accept: 'application/json' }, | ||
| cache: 'no-store', | ||
| }); | ||
| if (!response.ok) { | ||
| console.warn('[ConnectedMenuTop] organisation spaces fetch failed', { | ||
| status: response.status, | ||
| url, | ||
| }); | ||
| return []; | ||
| } | ||
| return (await response.json()) as Space[]; | ||
| }, | ||
| ); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Duplicate inline SWR fetchers — extract a shared helper
The two useSWR calls (Lines 55–72 and 73–92) share identical fetch logic: set Accept header, use cache: 'no-store', check response.ok, warn on failure, and cast the result. Extract a single generic fetcher to avoid divergence.
♻️ Proposed refactor
+async function jsonFetcher<T>(url: string, fallback: T): Promise<T> {
+ const response = await fetch(url, {
+ headers: { Accept: 'application/json' },
+ cache: 'no-store',
+ });
+ if (!response.ok) {
+ console.warn('[ConnectedMenuTop] fetch failed', { status: response.status, url });
+ return fallback;
+ }
+ return (await response.json()) as T;
+}
+
const { data: activeSpace, isLoading: isLoadingActiveSpace } =
useSWR<Space | null>(
activeSpaceSlug ? `/api/v1/spaces/${activeSpaceSlug}` : null,
- async (url: string) => {
- const response = await fetch(url, {
- headers: { Accept: 'application/json' },
- cache: 'no-store',
- });
- if (!response.ok) {
- console.warn('[ConnectedMenuTop] spaces fetch failed', {
- status: response.status,
- url,
- });
- return null;
- }
- return (await response.json()) as Space;
- },
+ (url: string) => jsonFetcher<Space | null>(url, null),
);
const { data: organisationSpaces = [], isLoading: isLoadingOrganisationSpaces } =
useSWR<Space[]>(
activeSpaceSlug ? `/api/v1/spaces/${activeSpaceSlug}/organisation` : null,
- async (url: string) => {
- const response = await fetch(url, {
- headers: { Accept: 'application/json' },
- cache: 'no-store',
- });
- if (!response.ok) {
- console.warn('[ConnectedMenuTop] organisation spaces fetch failed', {
- status: response.status,
- url,
- });
- return [];
- }
- return (await response.json()) as Space[];
- },
+ (url: string) => jsonFetcher<Space[]>(url, []),
);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/components/connected-menu-top.tsx` around lines 55 - 92, The two
useSWR calls (for activeSpace and organisationSpaces) duplicate the same inline
fetch logic; extract a shared generic fetcher function (e.g.,
apiJsonNoCacheFetcher<T>(url: string, contextLabel?: string): Promise<T | null |
T[]>) that sets Accept header, uses cache: 'no-store', checks response.ok, logs
a contextual warning (use the contextLabel like '[ConnectedMenuTop] activeSpace'
/ '[ConnectedMenuTop] organisationSpaces'), and returns the parsed JSON cast to
T (or a safe default like null or [] as appropriate). Replace the inline async
fetchers in the useSWR for activeSpace and organisationSpaces with calls to this
shared fetcher, preserving the return type casts and the same null/empty-array
fallback behavior.
| export function MyWalletTabs({ lang }: MyWalletTabsProps) { | ||
| const [activeTab, setActiveTab] = React.useState('wallet'); | ||
| const { isAuthenticated } = useAuthentication(); | ||
| const { person, isLoading } = useMe(); | ||
|
|
||
| if (isLoading) { | ||
| return <div className="py-4 text-sm text-muted-foreground">Loading...</div>; | ||
| } | ||
|
|
||
| if (!isAuthenticated || !person?.slug) { | ||
| return ( | ||
| <div className="py-4 text-sm text-muted-foreground"> | ||
| Sign in to view your wallet. | ||
| </div> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Hardcoded user-facing strings — must use next-intl
Every visible string is hardcoded instead of going through next-intl. Per the apps/web/** coding guidelines, there must be no hardcoded user-facing strings.
Affected strings:
- Line 24:
"Loading..." - Line 30:
"Sign in to view your wallet." - Lines 46, 49, 52:
"Wallet","Transactions","Rewards"
✏️ Proposed fix
+import { useTranslations } from 'next-intl';
export function MyWalletTabs({ lang }: MyWalletTabsProps) {
const [activeTab, setActiveTab] = React.useState('wallet');
const { isAuthenticated } = useAuthentication();
const { person, isLoading } = useMe();
+ const t = useTranslations('MyWallet');
if (isLoading) {
- return <div className="py-4 text-sm text-muted-foreground">Loading...</div>;
+ return <div className="py-4 text-sm text-muted-foreground">{t('loading')}</div>;
}
if (!isAuthenticated || !person?.slug) {
return (
<div className="py-4 text-sm text-muted-foreground">
- Sign in to view your wallet.
+ {t('signInPrompt')}
</div>
);
}
// ...
<TabsTrigger value="wallet" variant="switch">
- Wallet
+ {t('tabWallet')}
</TabsTrigger>
<TabsTrigger value="transactions" variant="switch">
- Transactions
+ {t('tabTransactions')}
</TabsTrigger>
<TabsTrigger value="rewards" variant="switch">
- Rewards
+ {t('tabRewards')}
</TabsTrigger>As per coding guidelines: "next-intl integration for i18n (no hardcoded user-facing strings)".
Also applies to: 43-54
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/components/my-wallet-tabs.tsx` around lines 18 - 33, Replace all
hardcoded user-facing strings in the MyWalletTabs component with next-intl
translation lookups using the provided lang prop; specifically, import and call
the translator (e.g., useTranslations or intl) in MyWalletTabs and replace
"Loading..." with t('loading') (or an equivalent key), "Sign in to view your
wallet." with t('signInToViewWallet'), and the tab labels "Wallet",
"Transactions", "Rewards" with t('tabs.wallet'), t('tabs.transactions'),
t('tabs.rewards') respectively; ensure keys are added to the relevant locale
files and keep the component's logic (isLoading, isAuthenticated, person?.slug,
activeTab, setActiveTab) unchanged while swapping literal strings for t(...)
calls.
Replace the missing getRootSpace dependency with a local root-space resolver and restore MenuTop logoNode support so connected-menu-top compiles against current UI exports.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/web/src/components/connected-menu-top.tsx (2)
154-158:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't gate the new connected branding behind
aiChatEnabled.This condition turns the new root-space logo path off on every space route whenever AI chat is disabled, so the branding added by this PR disappears in the default flag state. Either make this unconditional for space routes or introduce a dedicated branding flag instead of reusing the AI chat one. As per coding guidelines, "AI chat, Human chat, Coherence, and Space Memory are gated flags — off by default".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/connected-menu-top.tsx` around lines 154 - 158, Summary: The connected branding is incorrectly gated by aiChatEnabled causing the root-space logo to be hidden when AI chat is off. Fix: remove aiChatEnabled from the gating logic so the new branding path is active on space routes regardless of the AI chat flag—change suppressDefaultLogo to depend only on isSpaceRoute and keep canRenderSpaceLogoNode using rootSpace, isLoadingActiveSpace, and isLoadingOrganisationSpaces; alternatively if you prefer a feature flag, introduce a dedicated enableConnectedBranding boolean and use that instead of aiChatEnabled in suppressDefaultLogo.
187-189:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse
rootTitlefor the text fallback.When a space has no custom logo image, this renders the same generic label for every DHO, so the branding context is lost exactly on the fallback path. Showing
rootTitlefirst keeps the menu identifiable.💡 Suggested fix
<span className="relative truncate"> - {tNavigation('ecosystemLogo')} + {rootTitle || tNavigation('ecosystemLogo')} </span>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/connected-menu-top.tsx` around lines 187 - 189, Replace the generic fallback text so the menu shows the space branding: in the component that renders the span (connected-menu-top, where tNavigation('ecosystemLogo') is used), render rootTitle first and fall back to tNavigation('ecosystemLogo') if rootTitle is falsy (e.g. use rootTitle || tNavigation('ecosystemLogo')). Update the span content accordingly so the UI shows the specific rootTitle when no custom logo image exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/components/connected-menu-top.tsx`:
- Around line 53-62: The helper currently walks up parents using current.parent
or organisationById.get(current.parentId) and then returns the last seen current
even when a parent lookup failed; change the traversal so that if current.parent
is falsy and current.parentId is a number but
organisationById.get(current.parentId) returns undefined (i.e., nextParent is
unresolved), the function returns null instead of falling back to the child;
update the traversal in the block that computes nextParent (the variables
current, nextParent, organisationById, parentId) to detect this incomplete chain
and return null, and adjust the function signature/consumer handling if
necessary to accept a nullable return.
---
Outside diff comments:
In `@apps/web/src/components/connected-menu-top.tsx`:
- Around line 154-158: Summary: The connected branding is incorrectly gated by
aiChatEnabled causing the root-space logo to be hidden when AI chat is off. Fix:
remove aiChatEnabled from the gating logic so the new branding path is active on
space routes regardless of the AI chat flag—change suppressDefaultLogo to depend
only on isSpaceRoute and keep canRenderSpaceLogoNode using rootSpace,
isLoadingActiveSpace, and isLoadingOrganisationSpaces; alternatively if you
prefer a feature flag, introduce a dedicated enableConnectedBranding boolean and
use that instead of aiChatEnabled in suppressDefaultLogo.
- Around line 187-189: Replace the generic fallback text so the menu shows the
space branding: in the component that renders the span (connected-menu-top,
where tNavigation('ecosystemLogo') is used), render rootTitle first and fall
back to tNavigation('ecosystemLogo') if rootTitle is falsy (e.g. use rootTitle
|| tNavigation('ecosystemLogo')). Update the span content accordingly so the UI
shows the specific rootTitle when no custom logo image exists.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1366ae62-acb0-4f8f-b7e1-ec4c144c1fa6
📒 Files selected for processing (2)
apps/web/src/components/connected-menu-top.tsxpackages/ui/src/organisms/menu-top.tsx
|
🔗 Custom preview URL: https://pr-2227.preview-app.hypha.earth |
Add the global wallet entry and root ecosystem branding in the top bar so the home navigation reflects the new home-screen experience.
22a37a2 to
53a5850
Compare
Stack toolbar controls and action buttons on narrow viewports, use a wallet-specific single-column token grid until 720px, and tighten asset card text wrapping for small screens. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
My Walletentry and dedicated wallet page in the top navigationTest plan
pnpm run format:fixpnpm --filter web check-typesMade with Cursor
Summary by CodeRabbit