mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
feat(FE-113): create useSelect hook
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { ComponentType, ReactNode, useEffect, useMemo, useState } from 'react';
|
import { ComponentType, ReactNode, useEffect, useMemo, useState } from 'react';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
|
||||||
import Select, {
|
import Select, {
|
||||||
OptionProps,
|
OptionProps,
|
||||||
GroupBase,
|
GroupBase,
|
||||||
@@ -11,7 +13,10 @@ import Select, {
|
|||||||
import CreatableSelect from 'react-select/creatable';
|
import CreatableSelect from 'react-select/creatable';
|
||||||
import makeAnimated from 'react-select/animated';
|
import makeAnimated from 'react-select/animated';
|
||||||
import { useDebounce } from 'use-debounce';
|
import { useDebounce } from 'use-debounce';
|
||||||
import { cn } from '@/lib/helper';
|
import { cn, getByPath } from '@/lib/helper';
|
||||||
|
import { httpClientFetcher } from '@/services/http/client';
|
||||||
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
|
import { BaseApiResponse } from '@/types/api/api-general';
|
||||||
|
|
||||||
export interface OptionType {
|
export interface OptionType {
|
||||||
value: string | number;
|
value: string | number;
|
||||||
@@ -222,4 +227,45 @@ const SelectInput = <T extends OptionType>(props: SelectInputProps<T>) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const useSelect = <T,>(
|
||||||
|
basePath: string,
|
||||||
|
valueKey: keyof T,
|
||||||
|
labelKey: keyof T,
|
||||||
|
searchKey: string = 'search',
|
||||||
|
params?: { [key: string]: string }
|
||||||
|
) => {
|
||||||
|
const [inputValue, setInputValue] = useState('');
|
||||||
|
|
||||||
|
const optionsUrlParams = useMemo(() => {
|
||||||
|
return new URLSearchParams({
|
||||||
|
[searchKey]: inputValue ?? '',
|
||||||
|
...params,
|
||||||
|
}).toString();
|
||||||
|
}, [inputValue, searchKey]);
|
||||||
|
|
||||||
|
const optionsUrl = `${basePath}?${optionsUrlParams}`;
|
||||||
|
|
||||||
|
const { data, isLoading } = useSWR(optionsUrl, async (url) => {
|
||||||
|
return await httpClientFetcher<BaseApiResponse<T[]>>(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = isResponseSuccess(data)
|
||||||
|
? data.data.map((item) => {
|
||||||
|
return {
|
||||||
|
value: getByPath(item, valueKey as string),
|
||||||
|
label: getByPath(item, labelKey as string),
|
||||||
|
};
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
inputValue,
|
||||||
|
setInputValue,
|
||||||
|
options,
|
||||||
|
isLoadingOptions: isLoading,
|
||||||
|
rawData: data,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export { useSelect };
|
||||||
export default SelectInput;
|
export default SelectInput;
|
||||||
|
|||||||
Reference in New Issue
Block a user