[offers][feat] add query params to offer table (#502)
parent
70006d4115
commit
bd73a0b7b1
@ -0,0 +1,79 @@
|
|||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
type SearchParamOptions<Value> = [Value] extends [string]
|
||||||
|
? {
|
||||||
|
defaultValues?: Array<Value>;
|
||||||
|
paramToString?: (value: Value) => string | null;
|
||||||
|
stringToParam?: (param: string) => Value | null;
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
defaultValues?: Array<Value>;
|
||||||
|
paramToString: (value: Value) => string | null;
|
||||||
|
stringToParam: (param: string) => Value | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSearchParam = <Value = string>(
|
||||||
|
name: string,
|
||||||
|
opts?: SearchParamOptions<Value>,
|
||||||
|
) => {
|
||||||
|
const {
|
||||||
|
defaultValues,
|
||||||
|
stringToParam = (param: string) => param,
|
||||||
|
paramToString: valueToQueryParam = (value: Value) => String(value),
|
||||||
|
} = opts ?? {};
|
||||||
|
const [isInitialized, setIsInitialized] = useState(false);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const [params, setParams] = useState<Array<Value>>(defaultValues || []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (router.isReady && !isInitialized) {
|
||||||
|
// Initialize from query params
|
||||||
|
const query = router.query[name];
|
||||||
|
if (query) {
|
||||||
|
const queryValues = Array.isArray(query) ? query : [query];
|
||||||
|
setParams(
|
||||||
|
queryValues
|
||||||
|
.map(stringToParam)
|
||||||
|
.filter((value) => value !== null) as Array<Value>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setIsInitialized(true);
|
||||||
|
}
|
||||||
|
}, [isInitialized, name, stringToParam, router]);
|
||||||
|
|
||||||
|
const setParamsCallback = useCallback(
|
||||||
|
(newParams: Array<Value>) => {
|
||||||
|
setParams(newParams);
|
||||||
|
localStorage.setItem(
|
||||||
|
name,
|
||||||
|
JSON.stringify(
|
||||||
|
newParams.map(valueToQueryParam).filter((param) => param !== null),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[name, valueToQueryParam],
|
||||||
|
);
|
||||||
|
|
||||||
|
return [params, setParamsCallback, isInitialized] as const;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSearchParamSingle = <Value = string>(
|
||||||
|
name: string,
|
||||||
|
opts?: Omit<SearchParamOptions<Value>, 'defaultValues'> & {
|
||||||
|
defaultValue?: Value;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
const { defaultValue, ...restOpts } = opts ?? {};
|
||||||
|
const [params, setParams, isInitialized] = useSearchParam<Value>(name, {
|
||||||
|
defaultValues: defaultValue !== undefined ? [defaultValue] : undefined,
|
||||||
|
...restOpts,
|
||||||
|
} as SearchParamOptions<Value>);
|
||||||
|
|
||||||
|
return [
|
||||||
|
params[0],
|
||||||
|
(value: Value) => setParams([value]),
|
||||||
|
isInitialized,
|
||||||
|
] as const;
|
||||||
|
};
|
Loading…
Reference in new issue