이승윤

Merge branch 'feat/elasticsearch' into 'develop'

Feat/elasticsearch



See merge request !12
......@@ -22,4 +22,6 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
.vscode
\ No newline at end of file
.vscode
.env
\ No newline at end of file
......
REACT_APP_API_ENDPOINT={API_ENDPOINT}
REACT_APP_SEARCH_KEY={SEARCH_KEY}
REACT_APP_ENGINE_NAME={ENGINE_NAME}
\ No newline at end of file
......@@ -13,7 +13,9 @@
}],
"arrow-body-style": 1,
"react/jsx-fragments": 0,
"react/prop-types": 0
"react/prop-types": 0,
"import/prefer-default-export": 0,
"no-param-reassign": 0
},
"settings": {
"react": {
......
......@@ -5,10 +5,12 @@
"dependencies": {
"@mantine/core": "^1.0.6",
"@mantine/hooks": "^1.0.6",
"@reduxjs/toolkit": "^1.6.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.21.1",
"dotenv": "^10.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.2.0",
......
import React from 'react';
import { createGlobalStyle } from 'styled-components';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import dotenv from 'dotenv';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import SearchPage from './pages/SearchPage';
dotenv.config();
const GlobalStyle = createGlobalStyle`
html,
body,
......
......@@ -130,9 +130,7 @@ const Header = () => {
/>
</DropDownWrap>
</DropDownContainer>
<InputBlock color="blue" fontsize="20px" width="70%" display>
<input />
</InputBlock>
<InputBlock color="blue" fontsize="20px" width="70%" display />
</SearchContainer>
<MenuContainer>
<ul>
......
......@@ -2,8 +2,11 @@ import React, { useState, useEffect } from 'react';
import { TextInput } from '@mantine/core';
import styled from 'styled-components';
import { useHistory, useLocation } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import SearchBox from './SearchBox';
import { inputColorMap } from '../../lib/styles/palette';
import { esApi } from '../../lib/api/elasticsearch';
import { setParsedDocuments } from '../../features/parsedDocumentsSlice';
const InputBlock = styled.div`
width: ${props => props.width};
......@@ -42,10 +45,16 @@ const MyInput = ({
const history = useHistory();
const search = useLocation();
const name = search.search.substring(7);
const dispatch = useDispatch();
useEffect(() => {
const setSearchDatas = async () => {
const { results } = await esApi.search(name);
dispatch(setParsedDocuments(results));
};
setQuery(name);
}, []);
setSearchDatas();
}, [name]);
return (
<InputBlock
color={color}
......
import { createSlice } from '@reduxjs/toolkit';
const parsedDocumentsSlice = createSlice({
name: 'parsedDocuments',
initialState: {
documents: [],
},
reducers: {
setParsedDocuments: (state, action) => {
state.documents = action.payload;
},
},
});
export const { setParsedDocuments } = parsedDocumentsSlice.actions;
export default parsedDocumentsSlice.reducer;
import React from 'react';
import ReactDOM from 'react-dom';
import { configureStore } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';
import App from './App';
import rootReducer from './reducers';
const store = configureStore({
reducer: rootReducer,
});
ReactDOM.render(
<React.StrictMode>
<App />
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
......
import axios from 'axios';
const esInstance = axios.create({
baseURL: process.env.REACT_APP_API_ENDPOINT,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.REACT_APP_SEARCH_KEY}`,
},
});
export const esApi = {
search: async searchWord => {
const res = await esInstance.post(
`/api/as/v1/engines/${process.env.REACT_APP_ENGINE_NAME}/search`,
{
query: searchWord,
}
);
return res.data;
},
};
import React from 'react';
import { useSelector } from 'react-redux';
import Header from '../components/Header';
import Main from '../components/document/index';
import Main from '../components/document';
const SearchPage = () => {
const parsedDocuments = useSelector(state => state.parsedDocuments);
if (parsedDocuments.length === 0) {
return (
<>
<Header />
<div>검색 결과가 없습니다.</div>
</>
);
}
return (
<>
<Header />
......
import { combineReducers } from 'redux';
import parsedDocumentsReducer from '../features/parsedDocumentsSlice';
export default combineReducers({
parsedDocuments: parsedDocumentsReducer,
});
......@@ -1512,6 +1512,16 @@
schema-utils "^2.6.5"
source-map "^0.7.3"
"@reduxjs/toolkit@^1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.6.0.tgz#0a17c6941c57341f8b31e982352b495ab69d5add"
integrity sha512-eGL50G+Vj5AG5uD0lineb6rRtbs96M8+hxbcwkHpZ8LQcmt0Bm33WyBSnj5AweLkjQ7ZP+KFRDHiLMznljRQ3A==
dependencies:
immer "^9.0.1"
redux "^4.1.0"
redux-thunk "^2.3.0"
reselect "^4.0.0"
"@rollup/plugin-node-resolve@^7.1.1":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca"
......@@ -4359,6 +4369,11 @@ dotenv@8.2.0:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
dotenv@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
duplexer@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
......@@ -5902,6 +5917,11 @@ immer@8.0.1:
resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656"
integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==
immer@^9.0.1:
version "9.0.3"
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.3.tgz#146e2ba8b84d4b1b15378143c2345559915097f4"
integrity sha512-mONgeNSMuyjIe0lkQPa9YhdmTv8P19IeHV0biYhcXhbd5dhdB9HSK93zBpyKjp6wersSUgT5QyU0skmejUVP2A==
import-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
......@@ -9716,6 +9736,11 @@ redent@^3.0.0:
indent-string "^4.0.0"
strip-indent "^3.0.0"
redux-thunk@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
redux@^4.0.0, redux@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
......@@ -9724,6 +9749,13 @@ redux@^4.0.0, redux@^4.0.5:
loose-envify "^1.4.0"
symbol-observable "^1.2.0"
redux@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4"
integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==
dependencies:
"@babel/runtime" "^7.9.2"
regenerate-unicode-properties@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
......@@ -9896,6 +9928,11 @@ requires-port@^1.0.0:
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
reselect@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==
resolve-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
......