diff --git a/resources/js/components/app-sidebar.tsx b/resources/js/components/app-sidebar.tsx index 492e411b..3521a4a3 100644 --- a/resources/js/components/app-sidebar.tsx +++ b/resources/js/components/app-sidebar.tsx @@ -78,7 +78,9 @@ export function AppSidebar() { - + {footerNavItems.length > 0 && ( + + )} diff --git a/resources/js/components/user-menu-content.test.tsx b/resources/js/components/user-menu-content.test.tsx new file mode 100644 index 00000000..476a0fca --- /dev/null +++ b/resources/js/components/user-menu-content.test.tsx @@ -0,0 +1,95 @@ +import { type User } from '@/types'; +import { render, screen } from '@testing-library/react'; +import { type ReactNode } from 'react'; +import { describe, expect, it, vi } from 'vitest'; +import { UserMenuContent } from './user-menu-content'; + +vi.mock('@/components/ui/dropdown-menu', () => ({ + DropdownMenuGroup: ({ children }: { children: ReactNode }) => ( +
{children}
+ ), + DropdownMenuItem: ({ children }: { children: ReactNode }) => ( +
{children}
+ ), + DropdownMenuLabel: ({ children }: { children: ReactNode }) => ( +
{children}
+ ), + DropdownMenuSeparator: () =>
, +})); + +vi.mock('@/components/user-info', () => ({ + UserInfo: () =>
User
, +})); + +vi.mock('@/contexts/privacy-mode-context', () => ({ + usePrivacyMode: () => ({ + isPrivacyModeEnabled: false, + togglePrivacyMode: vi.fn(), + }), +})); + +vi.mock('@/hooks/use-mobile-navigation', () => ({ + useMobileNavigation: () => vi.fn(), +})); + +vi.mock('@/lib/key-storage', () => ({ + clearKey: vi.fn(), +})); + +vi.mock('@inertiajs/react', () => ({ + Link: ({ + children, + href, + ...props + }: { + children: ReactNode; + href: string; + as?: string; + prefetch?: boolean; + }) => { + delete props.as; + delete props.prefetch; + + return ( + + {children} + + ); + }, + router: { + flushAll: vi.fn(), + }, + usePage: () => ({ + props: { + version: 'test-version', + }, + }), +})); + +describe('UserMenuContent', () => { + it('shows community above feedback in the user dropdown', () => { + const user: User = { + id: '0194d20b-2b25-7000-8000-000000000001', + name: 'Test User', + email: 'test@example.com', + currency_code: 'USD', + locale: 'en', + timezone: 'UTC', + email_verified_at: null, + created_at: '2026-01-01T00:00:00.000000Z', + updated_at: '2026-01-01T00:00:00.000000Z', + }; + + render(); + + const community = screen.getByRole('link', { name: /community/i }); + const feedback = screen.getByRole('link', { name: /feedback/i }); + + expect(community.getAttribute('href')).toBe( + 'https://discord.gg/2WZmDW9QZ8', + ); + expect(community.compareDocumentPosition(feedback)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); + }); +}); diff --git a/resources/js/components/user-menu-content.tsx b/resources/js/components/user-menu-content.tsx index 67ec36d4..373a8c3b 100644 --- a/resources/js/components/user-menu-content.tsx +++ b/resources/js/components/user-menu-content.tsx @@ -1,3 +1,4 @@ +import DiscordIcon from '@/components/icons/DiscordIcon'; import { DropdownMenuGroup, DropdownMenuItem, @@ -92,6 +93,18 @@ export function UserMenuContent({ user }: UserMenuContentProps) { + + + + {__('Community')} + + { + it('does not include community in sidebar footer nav items', () => { + expect(footerNavItems).not.toContainEqual( + expect.objectContaining({ title: 'Community' }), + ); + }); +}); diff --git a/resources/js/providers/menu-item-provider.tsx b/resources/js/providers/menu-item-provider.tsx index 55ae59cb..602db216 100644 --- a/resources/js/providers/menu-item-provider.tsx +++ b/resources/js/providers/menu-item-provider.tsx @@ -1,7 +1,6 @@ import { index as accountsIndex } from '@/actions/App/Http/Controllers/AccountController'; import { index as budgetsIndex } from '@/actions/App/Http/Controllers/BudgetController'; import { index as transactionsIndex } from '@/actions/App/Http/Controllers/TransactionController'; -import DiscordIcon from '@/components/icons/DiscordIcon'; import { cashflow, dashboard } from '@/routes'; import { Features, NavItem } from '@/types'; import { @@ -81,11 +80,4 @@ export function getMainNavItems(features: Features, locale: string): NavItem[] { return items; } -export const footerNavItems: NavItem[] = [ - { - type: 'nav-item', - title: 'Community', - href: 'https://discord.gg/2WZmDW9QZ8', - icon: , - }, -]; +export const footerNavItems: NavItem[] = [];