From 6c71022ed63c734772feae7d93402f0528485a6d Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Fri, 27 Feb 2026 17:19:32 +0100 Subject: [PATCH] Move desktop filters to right side --- web/components/comments/dropdown-menu.tsx | 2 +- .../{mobile-filters.tsx => filters.tsx} | 146 ++++++---- web/components/filters/language-filter.tsx | 2 +- web/components/filters/mbti-filter.tsx | 2 +- web/components/filters/search.tsx | 51 +--- web/components/page-base.tsx | 8 +- web/components/profiles/profiles-home.tsx | 273 ++++++++++-------- web/pages/index.tsx | 4 +- web/styles/globals.css | 5 + 9 files changed, 260 insertions(+), 233 deletions(-) rename web/components/filters/{mobile-filters.tsx => filters.tsx} (88%) diff --git a/web/components/comments/dropdown-menu.tsx b/web/components/comments/dropdown-menu.tsx index 9c0954e2..a0dee85e 100644 --- a/web/components/comments/dropdown-menu.tsx +++ b/web/components/comments/dropdown-menu.tsx @@ -142,7 +142,7 @@ export function DropdownOptions(props: { } return ( - + {Object.entries(items).map(([key, item]) => (
- {isOpen && ( -
{children}
- )} + {isOpen &&
{children}
} ) } + +export function FiltersElement(props: { + filters: Partial + youProfile: Profile | undefined | null + updateFilter: (newState: Partial) => void + clearFilters: () => void + setYourFilters: (checked: boolean) => void + isYourFilters: boolean + locationFilterProps: LocationFilterProps + raisedInLocationFilterProps: LocationFilterProps +}) { + const { + filters, + youProfile, + updateFilter, + clearFilters, + setYourFilters, + isYourFilters, + locationFilterProps, + raisedInLocationFilterProps, + } = props + const youSeekingRelationship = youProfile?.pref_relation_styles?.includes('relationship') + const {choices: interestChoices} = useChoices('interests') + const {choices: causeChoices} = useChoices('causes') + const {choices: workChoices} = useChoices('work') + const choices = { + interests: interestChoices, + causes: causeChoices, + work: workChoices, + } + return ( + + ) +} diff --git a/web/components/filters/language-filter.tsx b/web/components/filters/language-filter.tsx index 02d4dcdb..bd8f256e 100644 --- a/web/components/filters/language-filter.tsx +++ b/web/components/filters/language-filter.tsx @@ -65,7 +65,7 @@ export function LanguageFilter(props: { onChange={(c) => { updateFilter({languages: c}) }} - optionsClassName={'w-[200px] sm:w-[400px]'} + optionsClassName={''} /> ) } diff --git a/web/components/filters/mbti-filter.tsx b/web/components/filters/mbti-filter.tsx index 194c3008..cef7a676 100644 --- a/web/components/filters/mbti-filter.tsx +++ b/web/components/filters/mbti-filter.tsx @@ -55,7 +55,7 @@ export function MbtiFilter(props: { return ( updateFilter: (newState: Partial) => void - clearFilters: () => void - setYourFilters: (checked: boolean) => void - isYourFilters: boolean locationFilterProps: LocationFilterProps - raisedInLocationFilterProps: LocationFilterProps bookmarkedSearches: BookmarkedSearchesType[] refreshBookmarkedSearches: () => void profileCount: number | undefined @@ -122,14 +116,12 @@ export const Search = forwardRef< highlightFilters?: boolean highlightSort?: boolean setOpenFiltersModal?: (open: boolean) => void + filtersElement: JSX.Element } >((props, ref) => { const { youProfile, updateFilter, - clearFilters, - setYourFilters, - isYourFilters, locationFilterProps, filters, bookmarkedSearches, @@ -142,7 +134,7 @@ export const Search = forwardRef< setOpenFiltersModal: parentSetOpenFiltersModal, highlightFilters, highlightSort, - raisedInLocationFilterProps, + filtersElement, } = props const [internalOpenFiltersModal, setInternalOpenFiltersModal] = useState(false) @@ -186,16 +178,8 @@ export const Search = forwardRef< const [openBookmarks, setOpenBookmarks] = useState(false) const [openStarBookmarks, setOpenStarBookmarks] = useState(false) const user = useUser() - const youSeekingRelationship = youProfile?.pref_relation_styles?.includes('relationship') const isClearedFilters = useIsClearedFilters(filters) const {choices: interestChoices} = useChoices('interests') - const {choices: causeChoices} = useChoices('causes') - const {choices: workChoices} = useChoices('work') - const choices = { - interests: interestChoices, - causes: causeChoices, - work: workChoices, - } useEffect(() => { if (isHolding) return @@ -269,41 +253,12 @@ export const Search = forwardRef< - - + {filtersElement} diff --git a/web/components/page-base.tsx b/web/components/page-base.tsx index d84a9517..7577ec9f 100644 --- a/web/components/page-base.tsx +++ b/web/components/page-base.tsx @@ -61,6 +61,12 @@ export function PageBase(props: { useOnline() const [_, setIsAddFundsModalOpen] = useState(false) + const colSpan = className?.split(' ').find((c) => c.startsWith('col-span-')) ?? 'col-span-8' + const restClassName = className + ?.split(' ') + .filter((c) => !c.startsWith('col-span-')) + .join(' ') + return ( <> @@ -88,7 +94,7 @@ export function PageBase(props: { className="sticky top-0 hidden self-start px-2 lg:col-span-2 lg:flex sidebar-nav bg-canvas-25" /> )} -
+
{children}
diff --git a/web/components/profiles/profiles-home.tsx b/web/components/profiles/profiles-home.tsx index fa0cfba5..1ecc8856 100644 --- a/web/components/profiles/profiles-home.tsx +++ b/web/components/profiles/profiles-home.tsx @@ -5,6 +5,7 @@ import {useRouter} from 'next/router' import {useCallback, useEffect, useRef, useState} from 'react' import toast from 'react-hot-toast' import {Button} from 'web/components/buttons/button' +import {FiltersElement} from 'web/components/filters/filters' import {Search} from 'web/components/filters/search' import {useFilters} from 'web/components/filters/use-filters' import {Col} from 'web/components/layout/col' @@ -184,147 +185,163 @@ export function ProfilesHome() { [refreshHiddenProfiles], ) + const filtersElement = ( + + ) + return ( - <> - {showBanner && fromSignup && ( -
- - - {t( - 'profiles.search_intention', - 'Compass works best when you search with intention. Try using keywords or filters instead of scrolling.', - )} - - - - {isMobile && ( +
+ + {showBanner && fromSignup && ( +
+ + + {t( + 'profiles.search_intention', + 'Compass works best when you search with intention. Try using keywords or filters instead of scrolling.', + )} + + + + {isMobile && ( + + )} - )} - - - -

+ + +

+ {t( + 'profiles.interactive_profiles', + 'Profiles are interactive — click any card to learn more and reach out.', + )} +

+
+ + +
+ )} + {showEarlyBanner && ( +
+ + {t( - 'profiles.interactive_profiles', - 'Profiles are interactive — click any card to learn more and reach out.', + 'profiles.early_growth', + `Compass is in its early growth phase — 500+ members and ~100 new people joining every month. Build a strong profile now and be visible as the community expands.`, + )} + + + +
+ )} + {/*{user && !profile && }*/} + {t('profiles.title', 'People')} + setOpenFiltersModal(true)} + openFiltersModal={openFiltersModal} + setOpenFiltersModal={setOpenFiltersModal} + highlightFilters={highlightFilters} + highlightSort={highlightSort} + youProfile={you} + starredUsers={starredUsers ?? []} + refreshStars={refreshStars} + filters={filters} + updateFilter={updateFilter} + locationFilterProps={locationFilterProps} + bookmarkedSearches={bookmarkedSearches} + refreshBookmarkedSearches={refreshBookmarkedSearches} + profileCount={profileCount} + filtersElement={filtersElement} + /> + {displayProfiles === undefined || compatibleProfiles === undefined ? ( + + ) : ( + <> + {fromSignup && isClearedFilters && ( +

+ {t( + 'profiles.seeing_all_profiles', + 'You are seeing all profiles. Use search or filters to narrow it down.', )}

- - - -
- )} - {showEarlyBanner && ( -
- - - {t( - 'profiles.early_growth', - `Compass is in its early growth phase — 500+ members and ~100 new people joining every month. Build a strong profile now and be visible as the community expands.`, - )} - - - -
- )} - {/*{user && !profile && }*/} - {t('profiles.title', 'People')} - setOpenFiltersModal(true)} - openFiltersModal={openFiltersModal} - setOpenFiltersModal={setOpenFiltersModal} - highlightFilters={highlightFilters} - highlightSort={highlightSort} - youProfile={you} - starredUsers={starredUsers ?? []} - refreshStars={refreshStars} - filters={filters} - updateFilter={updateFilter} - clearFilters={clearFilters} - setYourFilters={setYourFilters} - isYourFilters={isYourFilters} - locationFilterProps={locationFilterProps} - raisedInLocationFilterProps={raisedInLocationFilterProps} - bookmarkedSearches={bookmarkedSearches} - refreshBookmarkedSearches={refreshBookmarkedSearches} - profileCount={profileCount} - /> - {displayProfiles === undefined || compatibleProfiles === undefined ? ( - - ) : ( - <> - {fromSignup && isClearedFilters && ( -

- {t( - 'profiles.seeing_all_profiles', - 'You are seeing all profiles. Use search or filters to narrow it down.', - )} -

- )} - - - )} - + )} + + + )} + + {/* Desktop: filters sidebar on the right */} +
+ {filtersElement} +
+
) } diff --git a/web/pages/index.tsx b/web/pages/index.tsx index c333af9e..8eddef2b 100644 --- a/web/pages/index.tsx +++ b/web/pages/index.tsx @@ -20,9 +20,9 @@ export default function ProfilesPage() { console.debug('user:', user) return ( - + - + {user ? : } diff --git a/web/styles/globals.css b/web/styles/globals.css index a7a3cfc0..ff5544d9 100644 --- a/web/styles/globals.css +++ b/web/styles/globals.css @@ -8,9 +8,14 @@ --bnh: env(safe-area-inset-bottom); /* native bottom nav height */ --tnh: env(safe-area-inset-top); /* native top nav height */ --hloss: calc(var(--bnh) + var(--tnh)); /* mobile height loss due to native top and bottom bars */ + --filter-offset: 20px; /* padding for filters on mobile */ touch-action: pan-y; } +@media (width < 600px) { + --filter-offset: 0px; +} + .safe-top { /*padding-top: calc(20px);*/ padding-top: env(safe-area-inset-top);