Skip to content

Commit

Permalink
feat: SearchBar component 구현 resolve #186
Browse files Browse the repository at this point in the history
  • Loading branch information
NaGyeong-Park committed Dec 7, 2022
1 parent e76b218 commit c0f0bbf
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
125 changes: 125 additions & 0 deletions client/src/components/todos/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { ReactElement, useState } from 'react';
import { useAtomValue } from 'jotai';
import { toast } from 'react-toastify';

import { PlainTodo } from '@todo/todo.type';
import { todoList } from '@util/GlobalState';
import Search from '@images/Search.svg';

import Text from '@components/Text';
import Image from '@components/Image';
import styled from 'styled-components';
import { PRIMARY_COLORS } from '@util/Constants';

const Wrapper = styled.div`
position: relative;
width: 100%;
`;

const Ul = styled.ul`
list-style: none;
padding-left: 0px;
margin: 8px 0;
`;

const UlWrapper = styled.div`
position: absolute;
width: 100%;
margin: 10px 0;
background-color: white;
border: 1px solid #e2e2e2;
border-radius: 5px;
li:hover {
cursor: pointer;
background-color: ${PRIMARY_COLORS.lightGray};
}
`;

const ListWrapper = styled.div`
width: 100%;
display: flex;
align-items: center;
margin: 5px 0;
img {
margin: 0 5px;
}
p {
padding: 5px;
}
`;

const InputWrapper = styled(ListWrapper)`
display: flex;
justify-content: center;
background: white;
border: 1px solid ${PRIMARY_COLORS.lightGray};
border-radius: 5px;
padding: 3px 0;
`;

const SearchBar = ({ onClick }: { onClick: Function }): ReactElement => {
const todoListAtom = useAtomValue(todoList);
const [searchTodoList, setSearchTodoList] = useState<PlainTodo[]>([]);
const [inputValue, setInputValue] = useState('');

const inputEventPromiseWrapper = (event: React.ChangeEvent<HTMLInputElement>): void => {
onInput(event)
.then(() => {})
.catch(() => {});
};

const onInput = async (event: React.ChangeEvent<HTMLInputElement>): Promise<void> => {
setInputValue(event.target.value);
if (event.target.value.length > 1) {
return await todoListAtom
.getTodoBySearchKeyword(event.target.value, 10)
.then((data: PlainTodo[]) => {
setSearchTodoList((prev) => [...data]);
})
.catch((err) => {
toast.error(err);
});
}
};

const listOnClick = (selectTodo: PlainTodo): void => {
setInputValue('');
setSearchTodoList([]);
onClick(selectTodo);
};

return (
<Wrapper>
<InputWrapper>
<Image src={Search} />
<input
type="search"
value={inputValue}
onInput={inputEventPromiseWrapper}
style={{
border: 'none',
}}
/>
</InputWrapper>
{searchTodoList.length > 0 && (
<UlWrapper>
<Ul>
{searchTodoList.map((todo: PlainTodo) => {
return (
<li key={todo.id}>
<ListWrapper onClick={() => listOnClick(todo)}>
<Image src={Search} />
<Text text={todo.title} fontSize={'15px'} fontFamily={'SanSerif'} />
</ListWrapper>
</li>
);
})}
</Ul>
</UlWrapper>
)}
</Wrapper>
);
};

export default SearchBar;
2 changes: 1 addition & 1 deletion client/src/container/todos/TableModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const Container = styled.div`
position: relative;
width: 100%;
color: ${darkGray};
front-family: 'SanSerif'
font-family: 'SanSerif';
font-size: 15px;
padding: 5px;
border: 1px solid ${lightGray};
Expand Down
4 changes: 4 additions & 0 deletions client/src/images/Search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c0f0bbf

Please sign in to comment.