Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/llms-txt-hub / apps/web/hooks/use-website-filters.ts |
| Date | Not specified in source |
| Repository | Janady13/llms-txt-hub |
| Revision | e0f4bf978d4df168369c7601d9c5f5ea89e84377 |
| Branch | main |
| Path or archive member | apps/web/hooks/use-website-filters.ts |
| Original SHA-256 | d00cba5fdc943e002296882cb439cea3e252ae22b76c9fc9e276c3c0016bce50 |
| Git blob SHA | 96ec8a225e952c71f6eb64e7678ab868d7519c46 |
| Reading-copy SHA-256 | d00cba5fdc943e002296882cb439cea3e252ae22b76c9fc9e276c3c0016bce50 |
Recovered source transcript
Download complete source text ↓122 lines · 3.4 KB
'use client'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useCallback, useEffect, useState } from 'react'
interface UseWebsiteFiltersInput {
initialCategory?: string
initialSort?: string
includeCategory?: boolean // New option to control category handling
}
interface UseWebsiteFiltersOutput {
categoryFilter: string
sortBy: string
setCategoryFilter: (category: string) => void
setSortBy: (sort: string) => void
}
/**
* Hook to manage website filtering and sorting with URL synchronization
*
* @param options - Configuration options
* @param options.initialCategory - Initial category filter value (default: 'all')
* @param options.initialSort - Initial sort value (default: 'name')
*
* @returns Object containing filter state and setters
* @returns.categoryFilter - Current category filter value
* @returns.sortBy - Current sort value
* @returns.setCategoryFilter - Function to update category filter
* @returns.setSortBy - Function to update sort value
*
* @example
* ```tsx
* const { categoryFilter, sortBy, setCategoryFilter, setSortBy } = useWebsiteFilters({
* initialCategory: 'ai-ml',
* initialSort: 'latest'
* });
* ```
*/
export function useWebsiteFilters({
initialCategory = 'all',
initialSort = 'name',
includeCategory = true
}: UseWebsiteFiltersInput = {}): UseWebsiteFiltersOutput {
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()
// Initialize state from URL parameters or defaults
const [categoryFilter, setCategoryFilterState] = useState(
searchParams.get('category') || initialCategory
)
const [sortBy, setSortByState] = useState(searchParams.get('sort') || initialSort)
// Update URL when filters change
const updateUrl = useCallback(
(category: string, sort: string) => {
const params = new URLSearchParams(searchParams.toString())
// Only handle category if includeCategory is true
if (includeCategory) {
if (category === 'all') {
params.delete('category')
} else {
params.set('category', category)
}
}
if (sort === 'name') {
params.delete('sort')
} else {
params.set('sort', sort)
}
const queryString = params.toString()
const newUrl = queryString ? `${pathname}?${queryString}` : pathname
router.push(newUrl)
},
[pathname, router, searchParams, includeCategory]
)
// Handle category filter changes
const setCategoryFilter = useCallback(
(category: string) => {
setCategoryFilterState(category)
updateUrl(category, sortBy)
},
[sortBy, updateUrl]
)
// Handle sort changes
const setSortBy = useCallback(
(sort: string) => {
setSortByState(sort as string)
updateUrl(categoryFilter, sort)
},
[categoryFilter, updateUrl]
)
// Sync state with URL parameters on mount and URL changes
useEffect(() => {
const categoryFromUrl = searchParams.get('category')
const sortFromUrl = searchParams.get('sort')
if (categoryFromUrl !== categoryFilter) {
setCategoryFilterState(categoryFromUrl || initialCategory)
}
if (sortFromUrl !== sortBy) {
setSortByState((sortFromUrl as string) || initialSort)
}
}, [searchParams, initialCategory, initialSort])
return {
categoryFilter,
sortBy,
setCategoryFilter,
setSortBy
}
}