From 5186ad114b0eb578c7e7d64d860e46f1ca2ca4a2 Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Thu, 9 Apr 2026 13:59:28 +0200 Subject: [PATCH] Add "Pinned only" filter to Compatibility page using `Checkbox` component and update filtering logic accordingly --- web/pages/compatibility.tsx | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/web/pages/compatibility.tsx b/web/pages/compatibility.tsx index 77b1d259..38c69442 100644 --- a/web/pages/compatibility.tsx +++ b/web/pages/compatibility.tsx @@ -16,11 +16,13 @@ import {UncontrolledTabs} from 'web/components/layout/tabs' import {EnglishOnlyWarning} from 'web/components/news/english-only-warning' import {PageBase} from 'web/components/page-base' import {SEO} from 'web/components/SEO' +import {Checkbox} from 'web/components/widgets/checkbox' import {Input} from 'web/components/widgets/input' import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' import {Title} from 'web/components/widgets/title' import {LoadMoreUntilNotVisible} from 'web/components/widgets/visibility-observer' import {useIsMobile} from 'web/hooks/use-is-mobile' +import {usePinnedQuestionIds} from 'web/hooks/use-pinned-question-ids' import { useCompatibilityQuestionsWithAnswerCount, useUserCompatibilityAnswers, @@ -36,10 +38,12 @@ export default function CompatibilityPage() { const [searchTerm, setSearchTerm] = useState('') const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('') const [sort, setSort] = useState('random') + const [pinnedOnly, setPinnedOnly] = useState(false) const searchInputRef = useRef(null) const {compatibilityAnswers, refreshCompatibilityAnswers} = useUserCompatibilityAnswers(user?.id) const {compatibilityQuestions, refreshCompatibilityQuestions, isLoading} = useCompatibilityQuestionsWithAnswerCount() + const {pinnedQuestionIds, refreshPinnedQuestionIds} = usePinnedQuestionIds() const t = useT() // Debounce keyword changes @@ -64,12 +68,23 @@ export default function CompatibilityPage() { ...q, answer: answerMap.get(q.id), })) - .filter((qna) => isMatchingSearch(qna, debouncedSearchTerm)) + .filter((qna) => { + const matchesSearch = isMatchingSearch(qna, debouncedSearchTerm) + const isPinned = pinnedQuestionIds?.includes(qna.id) + return matchesSearch && (!pinnedOnly || isPinned) + }) return withAnswers.sort((a, b) => { return compareBySort(a, b, sort) }) as QuestionWithAnswer[] - }, [compatibilityQuestions, compatibilityAnswers, sort, debouncedSearchTerm]) + }, [ + compatibilityQuestions, + compatibilityAnswers, + sort, + debouncedSearchTerm, + pinnedQuestionIds, + pinnedOnly, + ]) const {answered, notAnswered, skipped} = useMemo(() => { const answered: QuestionWithAnswer[] = [] @@ -102,7 +117,8 @@ export default function CompatibilityPage() { const refreshCompatibilityAll = useCallback(() => { refreshCompatibilityAnswers() refreshCompatibilityQuestions() - }, [refreshCompatibilityAnswers, refreshCompatibilityQuestions]) + refreshPinnedQuestionIds() + }, [refreshCompatibilityAnswers, refreshCompatibilityQuestions, refreshPinnedQuestionIds]) return ( @@ -127,6 +143,11 @@ export default function CompatibilityPage() { setSearchTerm(e.target.value) }} /> +