Files
frontend/apps/fo/app/components/common/SearchInput.tsx
T

103 lines
4.1 KiB
TypeScript

import { useFoStore } from '@/app/store';
import type { facilityListProps } from '@/app/store/processFacility';
import { Label } from '@common/components/ui';
import React, { useEffect, useState, useRef, useCallback } from 'react'
type thisProps = {
label: string | undefined;
setValue : (fcltyCd?: string, fcltyNm?: string, fcltyCpc?: number | '', trtFrfNm?: string | '', efflWqltStndrdNm?: string | '') => void;
sidoSigun? : string | undefined;
fcltyName? : string | undefined;
}
export default function SearchInputText({label=undefined, setValue=()=>{}, sidoSigun=undefined, fcltyName=undefined} :thisProps) {
const { ProcessFacilityList, searchProcessFacilitySearching } = useFoStore((state) => state);
const [isOpen, setIsOpen] = useState(false);
const [textValue, setTextValue] = useState(fcltyName || '');
const wrapperRef = useRef<HTMLDivElement>(null);
const processFacilityList = ProcessFacilityList?.processFacilityList || [];
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setTextValue(value);
if (value) {
setIsOpen(true);
if(sidoSigun) {
searchProcessFacilitySearching(1, 4999, 'A', sidoSigun, '0', '0', '0', value);
} else {
searchProcessFacilitySearching(1, 4999, '0', '0', '0', '0', '0', value);
}
} else {
setIsOpen(false);
}
}, [searchProcessFacilitySearching, sidoSigun]);
const onInputFocus = useCallback(() => {
setIsOpen(true);
if(sidoSigun) {
searchProcessFacilitySearching(1, 4999, 'A', sidoSigun, '0', '0', '0');
} else {
searchProcessFacilitySearching(1, 4999, '0', '0', '0', '0', '0');
}
}, [searchProcessFacilitySearching, sidoSigun]);
useEffect(() => {
setTextValue(fcltyName || '');
}, [fcltyName]);
const handleSuggestionClick = useCallback((bscFctCd: string, bscFctNm: string, fctCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '') => {
setTextValue(bscFctNm);
setValue(bscFctCd, bscFctNm, fctCpc, trtFrfNm, efflWqltStndrdNm);
setIsOpen(false);
}, [setValue]);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
return (
<div className={'relative'} ref={wrapperRef}>
{label && <Label className="w-20 text-xl text-gray-600 justify-self-center">{label}</Label>}
<input
type="text"
value={textValue}
onChange={handleInputChange}
onFocus={onInputFocus}
className="w-[200px] ml-6 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder={`${label}을(를) 입력하세요`}
/>
{isOpen && processFacilityList.length > 0 && (
<div className="absolute z-10 w-[300px] px-2 py-1 !mt-5 ml-20 bg-white border border-gray-300 rounded-md shadow-lg h-90 overflow-auto">
<div className="max-h-72">
{processFacilityList.map((item : facilityListProps, index : number) => (
<div
key={index}
className="w-full text-left pl-1 pr-10 py-2 hover:bg-gray-100 cursor-pointer overflow-auto"
onClick={() => handleSuggestionClick(item.bscFctCd, item.bscFctNm, Number(item.fctCpc), item.trtFrfNm, item.efflWqltStndrdNm)}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
handleSuggestionClick(item.bscFctCd, item.bscFctNm, Number(item.fctCpc), item.trtFrfNm, item.efflWqltStndrdNm);
}
}}
>
{item.sido}&nbsp;{item.gugun}&nbsp;<span className="float-right">{item.bscFctNm}</span>
</div>
))}
</div>
</div>
)}
</div>
)
}