diff --git a/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/layout-client.tsx b/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/layout-client.tsx index 8afbe60..bc92d0e 100644 --- a/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/layout-client.tsx +++ b/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/layout-client.tsx @@ -44,7 +44,7 @@ const TabsWrapper: React.FC<{ boardDetails: BoardDetails }> = ({ boardDetails }) children: (
- +
diff --git a/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/page.tsx b/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/page.tsx index 4760f33..6ebbe8f 100644 --- a/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/page.tsx +++ b/app/[board_name]/[layout_id]/[size_id]/[set_ids]/[angle]/list/page.tsx @@ -76,7 +76,25 @@ export default async function DynamicResultsPage(props: { getBoardDetails(parsedParams), ]); - if (!fetchedResults || fetchedResults.climbs.length === 0) { + // Only show 404 if there are no climbs at all AND no filters are applied + // If filters are active and return 0 results, that's a valid empty state + const hasActiveFilters = + searchParamsObject.name || + searchParamsObject.minGrade || + searchParamsObject.maxGrade || + searchParamsObject.minAscents || + searchParamsObject.minRating || + searchParamsObject.onlyClassics || + searchParamsObject.tallClimbsOnly || + searchParamsObject.gradeAccuracy || + searchParamsObject.settername.length > 0 || + Object.keys(searchParamsObject.holdsFilter).length > 0 || + searchParamsObject.hideAttempted || + searchParamsObject.hideCompleted || + searchParamsObject.showOnlyAttempted || + searchParamsObject.showOnlyCompleted; + + if (!fetchedResults || (fetchedResults.climbs.length === 0 && !hasActiveFilters)) { notFound(); } diff --git a/app/components/queue-control/__tests__/hooks/use-queue-data-fetching.test.tsx b/app/components/queue-control/__tests__/hooks/use-queue-data-fetching.test.tsx index a589129..7cb3fbf 100644 --- a/app/components/queue-control/__tests__/hooks/use-queue-data-fetching.test.tsx +++ b/app/components/queue-control/__tests__/hooks/use-queue-data-fetching.test.tsx @@ -81,7 +81,8 @@ const mockSearchParams: SearchRequestPagination = { hideAttempted: false, hideCompleted: false, showOnlyAttempted: false, - showOnlyCompleted: false + showOnlyCompleted: false, + tallClimbsOnly: false }; const mockParsedParams: ParsedBoardRouteParameters = { diff --git a/app/components/queue-control/__tests__/reducer.test.ts b/app/components/queue-control/__tests__/reducer.test.ts index 34b11b5..22da6d3 100644 --- a/app/components/queue-control/__tests__/reducer.test.ts +++ b/app/components/queue-control/__tests__/reducer.test.ts @@ -47,7 +47,8 @@ const mockSearchParams: SearchRequestPagination = { hideAttempted: false, hideCompleted: false, showOnlyAttempted: false, - showOnlyCompleted: false + showOnlyCompleted: false, + tallClimbsOnly: false }; const initialState: QueueState = { @@ -292,7 +293,8 @@ describe('queueReducer', () => { hideAttempted: false, hideCompleted: false, showOnlyAttempted: false, - showOnlyCompleted: false + showOnlyCompleted: false, + tallClimbsOnly: false }; const action: QueueAction = { diff --git a/app/components/queue-control/ui-searchparams-provider.tsx b/app/components/queue-control/ui-searchparams-provider.tsx index 9b4d2ef..456fce9 100644 --- a/app/components/queue-control/ui-searchparams-provider.tsx +++ b/app/components/queue-control/ui-searchparams-provider.tsx @@ -41,6 +41,7 @@ export const UISearchParamsProvider: React.FC<{ children: React.ReactNode }> = ( if (uiSearchParams.hideCompleted) activeFilters.push('hideCompleted'); if (uiSearchParams.showOnlyAttempted) activeFilters.push('showOnlyAttempted'); if (uiSearchParams.showOnlyCompleted) activeFilters.push('showOnlyCompleted'); + if (uiSearchParams.tallClimbsOnly) activeFilters.push('tallClimbsOnly'); if (activeFilters.length > 0) { track('Climb Search Performed', { diff --git a/app/components/search-drawer/basic-search-form.tsx b/app/components/search-drawer/basic-search-form.tsx index e648135..4678fec 100644 --- a/app/components/search-drawer/basic-search-form.tsx +++ b/app/components/search-drawer/basic-search-form.tsx @@ -7,15 +7,21 @@ import { useUISearchParams } from '@/app/components/queue-control/ui-searchparam import { useBoardProvider } from '@/app/components/board-provider/board-provider-context'; import SearchClimbNameInput from './search-climb-name-input'; import SetterNameSelect from './setter-name-select'; +import { BoardDetails } from '@/app/lib/types'; const { Title } = Typography; -const BasicSearchForm: React.FC = () => { +interface BasicSearchFormProps { + boardDetails: BoardDetails; +} + +const BasicSearchForm: React.FC = ({ boardDetails }) => { const { uiSearchParams, updateFilters } = useUISearchParams(); const { token, user_id } = useBoardProvider(); const grades = TENSION_KILTER_GRADES; - + const isLoggedIn = token && user_id; + const isLargestSize = boardDetails.isLargestSize ?? false; const handleGradeChange = (type: 'min' | 'max', value: number | undefined) => { if (type === 'min') { @@ -178,6 +184,16 @@ const BasicSearchForm: React.FC = () => { /> + {isLargestSize && ( + + updateFilters({ tallClimbsOnly: checked })} + /> + + )} +