fix(ui): восстанавливать поиск и фильтры BGP из URL

This commit is contained in:
Denozordec committed 2026-09-30 17:15:37 +07:00
1 parent 5c307a5b6c
commit aa678b9d5d
8 files changed
+220 -16

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
"use client"
import { useEffect, useMemo, useState } from "react"
import { useSearchParams } from "next/navigation"
import type { FilterQuery } from "@/components/reui/filters/filters-types"
import { encodeBgpQuery, patchBgpUrl, readBgpUrl, validateBgpQuery, type BgpTypeFilter, type BgpStateFilter } from "@/lib/data-filters/bgp-url-state"
export function useBgpUrlState() {
const params = useSearchParams()
const raw = params.toString()
const state = useMemo(() => readBgpUrl(new URLSearchParams(raw)), [raw])
const filterKey = params.get("filters")
const [draft, setDraft] = useState<{ key: string | null; query: FilterQuery; error: string | null } | null>(null)
useEffect(() => {
const reset = () => setDraft(null)
window.addEventListener("popstate", reset)
return () => window.removeEventListener("popstate", reset)
}, [])
function write(changes: Record<string, string | null>, replace = false) {
const href = patchBgpUrl(new URLSearchParams(window.location.search), changes)
if (href === window.location.pathname + window.location.search) return
if (replace) window.history.replaceState(null, "", href)
else window.history.pushState(null, "", href)
}
function setFilters(query: FilterQuery) {
if (validateBgpQuery(query) === "draft") { setDraft({ key: filterKey, query, error: null }); return }
try {
const encoded = encodeBgpQuery(query)
setDraft(null)
write({ filters: encoded })
} catch (error) {
setDraft({ key: filterKey, query, error: error instanceof Error ? error.message : "Некорректный фильтр." })
}
}
const currentDraft = draft?.key === filterKey ? draft : null
return {
search: state.search,
typeFilter: state.type,
stateFilter: state.state,
filters: currentDraft?.query ?? state.query,
error: state.error ?? currentDraft?.error ?? null,
hasFilters: params.has("q") || params.has("type") || params.has("state") || params.has("filters") || currentDraft !== null,
setSearch: (value: string) => write({ q: value }, true),
setTypeFilter: (value: BgpTypeFilter) => write({ type: value === "all" ? null : value }),
setStateFilter: (value: BgpStateFilter) => write({ state: value === "all" ? null : value }),
setFilters,
reset: () => { setDraft(null); write({ q: null, type: null, state: null, filters: null }) },
}
}