useLogsUrlState.ts115 lines · main
1import { createParser, useQueryState } from 'nuqs'
2
3import { Filters } from '@/components/interfaces/Settings/Logs/Logs.types'
4
5interface LogsUrlState {
6 search: string
7 timestampStart: string
8 timestampEnd: string
9 selectedLogId: string | null
10 filters: Filters
11}
12
13const defaultState: LogsUrlState = {
14 search: '',
15 timestampStart: '',
16 timestampEnd: '',
17 selectedLogId: null,
18 filters: {},
19}
20
21const stringWithDefault = (defaultValue: string) =>
22 createParser({
23 parse: (v) => v ?? defaultValue,
24 serialize: (v) => v || '',
25 })
26
27const jsonWithDefault = <T>(defaultValue: T) =>
28 createParser({
29 parse: (v) => {
30 if (!v) return defaultValue
31 try {
32 return JSON.parse(v) as T
33 } catch (e) {
34 return defaultValue
35 }
36 },
37 serialize: (v) => {
38 if (!v) return ''
39 try {
40 return JSON.stringify(v)
41 } catch (e) {
42 return ''
43 }
44 },
45 })
46
47export function useLogsUrlState() {
48 const [searchValue, setSearchValue] = useQueryState('s', stringWithDefault(defaultState.search))
49 const [timestampStartValue, setTimestampStartValue] = useQueryState(
50 'its',
51 stringWithDefault(defaultState.timestampStart)
52 )
53 const [timestampEndValue, setTimestampEndValue] = useQueryState(
54 'ite',
55 stringWithDefault(defaultState.timestampEnd)
56 )
57 const [selectedLogIdValue, setSelectedLogIdValue] = useQueryState('log', stringWithDefault(''))
58 const [filtersValue, setFiltersValue] = useQueryState(
59 'f',
60 jsonWithDefault<Filters>(defaultState.filters)
61 )
62
63 // Ensure we never return null values
64 const search = searchValue || defaultState.search
65 const timestampStart = timestampStartValue || defaultState.timestampStart
66 const timestampEnd = timestampEndValue || defaultState.timestampEnd
67 const selectedLogId = selectedLogIdValue || null
68 const filters = filtersValue || defaultState.filters
69
70 const setSearch = (value: string) => {
71 setSearchValue(value || defaultState.search)
72 }
73
74 const setTimeRange = (start: string, end: string) => {
75 setTimestampStartValue(start || defaultState.timestampStart)
76 setTimestampEndValue(end || defaultState.timestampEnd)
77 }
78
79 const setSelectedLogId = (value: string | null) => {
80 setSelectedLogIdValue(value || '')
81 }
82
83 const setFilters = (value: Filters) => {
84 setFiltersValue(value || defaultState.filters)
85 }
86
87 const updateFilter = (key: string, value: any) => {
88 setFilters({ ...filters, [key]: value })
89 }
90
91 const reset = () => {
92 setSearch(defaultState.search)
93 setTimestampStartValue(defaultState.timestampStart)
94 setTimestampEndValue(defaultState.timestampEnd)
95 setSelectedLogIdValue('')
96 setFiltersValue(defaultState.filters)
97 }
98
99 return {
100 // State
101 search,
102 timestampStart,
103 timestampEnd,
104 selectedLogId,
105 filters,
106
107 // Setters
108 setSearch,
109 setTimeRange,
110 setSelectedLogId,
111 setFilters,
112 updateFilter,
113 reset,
114 }
115}