7d8e2d1192
On mobile the profile page used to stack the full identity rail
(avatar / bio / actions / stats / campaigns / latest pledge / orgs
/ fields) above the tab bar. Users had to scroll past the entire
rail before they reached the tabs, and once the tabs did pin they
clashed with the main app top nav.
Reshape the mobile layout so the rail's content becomes a tab. The
avatar, name, bio, action bar, and Followers/Following/Raised stats
stay above the tab bar as a persistent identity header; everything
else moves into two new mobile-only tabs:
Mobile: Overview | Activity | Campaigns | Community | Pledges
Desktop: Activity | Campaigns | Pledges (unchanged)
Overview shows the campaigns preview, the fallback latest-pledge
card, and the freeform kind-0 profile fields. Community shows the
organizations grid. Desktop is byte-identical — the two-column
grid with the sticky 340px rail still renders the original three
content tabs.
Implementation:
- Split ProfileIdentityRail.tsx into reusable exports:
ProfileAvatarBlock, ProfileIdentityHeader, ProfileOverviewSections
(with an opt-out showOrganizations flag), and a standalone
ProfileOrganizationsSection for the Community tab. The original
ProfileIdentityRail wrapper still composes them in the same
two-layer structure used by the desktop sticky aside.
- ProfilePage.tsx now renders two parallel layouts toggled with
hidden / lg:hidden (no useIsMobile, so no first-render flicker).
A new ProfileTabContent helper routes the active tab id to its
body for both layouts.
- Initial activeTab is picked from matchMedia('(min-width: 1024px)')
so mobile defaults to 'overview' and desktop to 'activity'
without a wrong-tab flash. Resizing from mobile to desktop while
on overview / community redirects to activity.