diff --git a/src/components/Input/index.tsx b/src/components/Input/index.tsx
index 453c742..a647831 100644
--- a/src/components/Input/index.tsx
+++ b/src/components/Input/index.tsx
@@ -2,6 +2,7 @@ import "./input.scss";
import { fetchData } from "../../utils/fetch-data";
import { debounce } from "../../utils/deboucne";
import Loader from "../Loader";
+import { useEffect, useState } from "react";
export interface InputProps {
/** Placeholder of the input */
@@ -10,14 +11,128 @@ export interface InputProps {
onSelectItem: (item: string) => void;
}
+export interface IListItemProps {
+ onSelectItem: (item: string) => void;
+ searchValue: string;
+}
+
+const SearchItem = ({ onSelectItem, searchValue }: IListItemProps) => {
+ return (
+
+
+
+ );
+};
+
const Input = ({ placeholder, onSelectItem }: InputProps) => {
// DO NOT remove this log
- console.log('input re-render')
+ console.log("input re-render");
// Your code start here
- return
+ const [inputValue, setInputValue] = useState('');
+ const [searchResults, setSearchReullt] = useState<{
+ searchResults: string[];
+ errorMessage: string;
+ }>({
+ searchResults: [],
+ errorMessage: '',
+ });
+ const [isLoading, setIsLoading] = useState(false);
+ const handleInputChange = debounce(
+ async (event: React.ChangeEvent) => {
+ setInputValue(event.target.value);
+ },
+ 100
+ );
+
+ useEffect(() => {
+ if (!inputValue) return;
+
+ setIsLoading(true);
+ let isMounted = true;
+ const getSearchResults = async () => {
+ try {
+ const response = await fetchData(inputValue);
+
+ if (!isMounted) return;
+
+ if (response && response.length > 0) {
+ setSearchReullt({
+ searchResults: response,
+ errorMessage: ''
+ });
+ return;
+ }
+
+ setSearchReullt({
+ searchResults: [],
+ errorMessage: 'No result found',
+ });
+ } catch(error) {
+ setSearchReullt({
+ searchResults: [],
+ errorMessage: error as unknown as string
+ });
+ } finally {
+ if (isMounted) {
+ setIsLoading(false)
+ }
+ }
+
+ }
+
+ getSearchResults();
+
+ return () => {
+ isMounted = false;
+ }
+ }, [inputValue])
+
+ return (
+
+
+ {inputValue && (
+
+ {isLoading &&
}
+ {!isLoading && searchResults.searchResults && searchResults.searchResults.length > 0 && (
+
+
+ {searchResults.searchResults &&
+ searchResults.searchResults.map((results, index) => {
+ return (
+
+ );
+ })}
+
+
+ )}
+ {
+ !isLoading && searchResults.searchResults && searchResults.searchResults.length === 0 && (
+
+ {searchResults.errorMessage}
+
+ )
+ }
+
+ )}
+
+ );
// Your code end here
};
export default Input;
-
diff --git a/src/components/Input/input.scss b/src/components/Input/input.scss
index 1dafbe7..d175b51 100644
--- a/src/components/Input/input.scss
+++ b/src/components/Input/input.scss
@@ -4,3 +4,51 @@
html{
font-size: 16px;
}
+
+.input-search {
+ &__input {
+ border-radius: 4px;
+ line-height: 1.5em;
+ font-size: 16px;
+ padding: .5em 1em;
+ width: 100%;
+ }
+
+ &__search-results-wrapper {
+ width: 100%;
+ position: relative;
+ border-radius: 4px;
+ min-height: 100px;
+ border: solid 1px #ddd;
+ margin-top: 4px;
+ }
+
+ &__error-message {
+ color: red;
+ font-style: italic;
+ padding: .5em 1em;
+ }
+
+ &__search-item {
+ list-style-type: none;
+ font-size: 16px;
+ text-align: center;
+ padding: 1em 2em;
+ cursor: pointer;
+
+ &:hover {
+ background-color: #eee;
+ }
+ }
+
+ &__item {
+ background-color: inherit;
+ outline: none;
+ border: none
+ }
+
+ &__list-item {
+ padding: 0;
+ margin: 0
+ }
+}