Skip to content

Commit 62da217

Browse files
committed
utils file
1 parent 8d9de39 commit 62da217

File tree

2 files changed

+98
-50
lines changed

2 files changed

+98
-50
lines changed

src/components/ChangelogFilters/ChangelogFilters.tsx

Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import styles from "./styles.module.css"
2-
import { useState, useEffect, useCallback } from "react"
2+
import { useState, useEffect } from "react"
33
import type { ChangelogItem } from "~/components/ChangelogSnippet/types"
44
import { matchesFilters } from "~/utils/changelogFilters"
5+
import { parseURLParams, updateFilterURL, toggleItemInArray } from "~/utils/changelogFilterUtils"
56
import { DesktopFilters } from "./DesktopFilters"
67
import { MobileFilters } from "./MobileFilters"
78

@@ -21,58 +22,20 @@ export const ChangelogFilters = ({ products, networks, types, items }: Changelog
2122

2223
// Read URL parameters on mount
2324
useEffect(() => {
24-
if (typeof window === "undefined") return
25-
26-
const params = new URLSearchParams(window.location.search)
27-
const productParam = params.get("product")
28-
const networkParam = params.get("network")
29-
const typeParam = params.get("type")
30-
const searchParam = params.get("*")
25+
const urlParams = parseURLParams()
3126

32-
if (productParam) {
33-
setSelectedProducts(productParam.split(","))
34-
}
35-
if (networkParam) {
36-
setSelectedNetworks(networkParam.split(","))
37-
}
38-
if (typeParam) {
39-
setSelectedTypes(typeParam.split(","))
40-
}
41-
if (searchParam) {
42-
setSearchTerm(searchParam)
43-
setSearchExpanded(true)
44-
}
27+
setSelectedProducts(urlParams.products)
28+
setSelectedNetworks(urlParams.networks)
29+
setSelectedTypes(urlParams.types)
30+
setSearchTerm(urlParams.searchTerm)
31+
setSearchExpanded(urlParams.searchExpanded)
4532
}, [])
4633

4734

48-
// Update URL whenever filters change
49-
const updateURL = useCallback((products: string[], networks: string[], types: string[], search: string) => {
50-
if (typeof window === "undefined") return
51-
52-
const params = new URLSearchParams()
53-
54-
if (search) {
55-
params.set("*", search)
56-
} else {
57-
if (products.length > 0) {
58-
params.set("product", products.join(","))
59-
}
60-
if (networks.length > 0) {
61-
params.set("network", networks.join(","))
62-
}
63-
if (types.length > 0) {
64-
params.set("type", types.join(","))
65-
}
66-
}
67-
68-
const newURL = params.toString() ? `?${params.toString()}` : window.location.pathname
69-
window.history.replaceState({}, "", newURL)
70-
}, [])
71-
7235
// Update URL when filters change
7336
useEffect(() => {
74-
updateURL(selectedProducts, selectedNetworks, selectedTypes, searchTerm)
75-
}, [selectedProducts, selectedNetworks, selectedTypes, searchTerm, updateURL])
37+
updateFilterURL(selectedProducts, selectedNetworks, selectedTypes, searchTerm)
38+
}, [selectedProducts, selectedNetworks, selectedTypes, searchTerm])
7639

7740
// Filter items and update the display
7841
useEffect(() => {
@@ -186,13 +149,13 @@ export const ChangelogFilters = ({ products, networks, types, items }: Changelog
186149
const toggleSelection = (type: "product" | "network" | "type", value: string) => {
187150
switch (type) {
188151
case "product":
189-
setSelectedProducts((prev) => (prev.includes(value) ? prev.filter((p) => p !== value) : [...prev, value]))
152+
setSelectedProducts((prev) => toggleItemInArray(prev, value))
190153
break
191154
case "network":
192-
setSelectedNetworks((prev) => (prev.includes(value) ? prev.filter((n) => n !== value) : [...prev, value]))
155+
setSelectedNetworks((prev) => toggleItemInArray(prev, value))
193156
break
194157
case "type":
195-
setSelectedTypes((prev) => (prev.includes(value) ? prev.filter((t) => t !== value) : [...prev, value]))
158+
setSelectedTypes((prev) => toggleItemInArray(prev, value))
196159
break
197160
}
198161
}

src/utils/changelogFilterUtils.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* Utility functions for changelog filter management
3+
*/
4+
5+
/**
6+
* Parse URL parameters to extract filter state
7+
*/
8+
export function parseURLParams(): {
9+
products: string[]
10+
networks: string[]
11+
types: string[]
12+
searchTerm: string
13+
searchExpanded: boolean
14+
} {
15+
if (typeof window === "undefined") {
16+
return {
17+
products: [],
18+
networks: [],
19+
types: [],
20+
searchTerm: "",
21+
searchExpanded: false,
22+
}
23+
}
24+
25+
const params = new URLSearchParams(window.location.search)
26+
const productParam = params.get("product")
27+
const networkParam = params.get("network")
28+
const typeParam = params.get("type")
29+
const searchParam = params.get("*")
30+
31+
return {
32+
products: productParam ? productParam.split(",") : [],
33+
networks: networkParam ? networkParam.split(",") : [],
34+
types: typeParam ? typeParam.split(",") : [],
35+
searchTerm: searchParam || "",
36+
searchExpanded: !!searchParam,
37+
}
38+
}
39+
40+
/**
41+
* Build URL search parameters from filter state
42+
*/
43+
export function buildFilterURL(
44+
products: string[],
45+
networks: string[],
46+
types: string[],
47+
searchTerm: string
48+
): URLSearchParams {
49+
const params = new URLSearchParams()
50+
51+
if (searchTerm) {
52+
params.set("*", searchTerm)
53+
} else {
54+
if (products.length > 0) {
55+
params.set("product", products.join(","))
56+
}
57+
if (networks.length > 0) {
58+
params.set("network", networks.join(","))
59+
}
60+
if (types.length > 0) {
61+
params.set("type", types.join(","))
62+
}
63+
}
64+
65+
return params
66+
}
67+
68+
/**
69+
* Update browser URL with filter parameters
70+
*/
71+
export function updateFilterURL(products: string[], networks: string[], types: string[], searchTerm: string): void {
72+
if (typeof window === "undefined") return
73+
74+
const params = buildFilterURL(products, networks, types, searchTerm)
75+
const newURL = params.toString() ? `?${params.toString()}` : window.location.pathname
76+
77+
window.history.replaceState({}, "", newURL)
78+
}
79+
80+
/**
81+
* Toggle an item in an array (add if not present, remove if present)
82+
*/
83+
export function toggleItemInArray<T>(array: T[], item: T): T[] {
84+
return array.includes(item) ? array.filter((i) => i !== item) : [...array, item]
85+
}

0 commit comments

Comments
 (0)