Skip to content

Commit

Permalink
13-4 [FE] [논문 상세 - 논문 정보] 검색한 논문의 제목, 저자, DOI, 인용논문 목록을 보여주고, DOI 클릭 …
Browse files Browse the repository at this point in the history
…시 논문 원본으로 이동한다. (#76)
  • Loading branch information
Palwol authored Nov 30, 2022
1 parent 48cb5dc commit bea4df2
Show file tree
Hide file tree
Showing 21 changed files with 363 additions and 56 deletions.
4 changes: 3 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { ReactQueryDevtools } from 'react-query/devtools';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import { Reset } from 'styled-reset';
import { PATH_MAIN, PATH_SEARCH_LIST } from './constants/path';
import { PATH_DETAIL, PATH_MAIN, PATH_SEARCH_LIST } from './constants/path';
import Main from './pages/Main/Main';
import SearchList from './pages/SearchList/SearchList';
import PaperDatail from './pages/PaperDetail/PaperDetail';
import GlobalStyle from './style/GlobalStyle';
import theme from './style/theme';

Expand All @@ -30,6 +31,7 @@ function App() {
<Routes>
<Route path={PATH_MAIN} element={<Main />} />
<Route path={PATH_SEARCH_LIST} element={<SearchList />} />
<Route path={PATH_DETAIL} element={<PaperDatail />} />
</Routes>
<ReactQueryDevtools initialIsOpen={true} />
</QueryClientProvider>
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export interface IGetAutoComplete {
keyword: string;
}

export interface IGetPaperDetail {
doi: string;
}

export default class Api {
private readonly baseURL = 'http://49.50.172.204:4000/';
private readonly instance: AxiosInstance;
Expand All @@ -31,4 +35,8 @@ export default class Api {
getAutoComplete(params: IGetAutoComplete) {
return this.instance.get('/search/auto-complete', { params });
}

getPaperDetail(params: IGetPaperDetail) {
return this.instance.get(`/search/paper`, { params });
}
}
21 changes: 21 additions & 0 deletions frontend/src/components/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from 'styled-components';

interface IProps {
icon: JSX.Element;
onClick: React.MouseEventHandler;
}

const IconButton = ({ icon, onClick }: IProps) => {
return (
<Button type="button" onClick={onClick}>
{icon}
</Button>
);
};

const Button = styled.button`
background-color: transparent;
cursor: pointer;
`;

export default IconButton;
12 changes: 0 additions & 12 deletions frontend/src/components/Logo.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import { Dispatch, SetStateAction, useEffect } from 'react';
import styled from 'styled-components';
import { MAX_TITLE_LENGTH } from '../constants/main';
import { MAX_TITLE_LENGTH } from '../../constants/main';
import { IAutoCompletedItem } from './Search';

interface AutoCompletedListProps {
autoCompletedItems?: IAutoCompletedItem[];
keyword: string;
hoverdIndex: number;
setHoveredIndex: Dispatch<SetStateAction<number>>;
handleMouseDown: (doi: string) => void;
}

const AutoCompletedList = ({
autoCompletedItems = [],
keyword,
hoverdIndex,
setHoveredIndex,
handleMouseDown,
}: AutoCompletedListProps) => {
const handleAutoCompletedDown = (index: number) => {
// Todo : 상세정보 api 호출
console.log('상세정보', autoCompletedItems[index].doi);
const doi = autoCompletedItems[index].doi;
handleMouseDown(doi);
};

// keyword 강조
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isEmpty } from 'lodash-es';
import { Dispatch, SetStateAction, useEffect } from 'react';
import styled from 'styled-components';
import Clockicon from '../icons/ClockIcon';
import Clockicon from '../../icons/ClockIcon';

interface RecentKeywordsListProps {
recentKeywords: string[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import { ChangeEvent, KeyboardEvent, useCallback, useEffect, useMemo, useRef, us
import { useQuery } from 'react-query';
import { createSearchParams, useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import Api from '../api/api';
import { PATH_SEARCH_LIST } from '../constants/path';
import useDebounceValue from '../customHooks/useDebouncedValue';
import MaginifyingGlassIcon from '../icons/MagnifyingGlassIcon';
import { getLocalStorage, setLocalStorage } from '../utils/localStorage';
import Api from '../../api/api';
import { PATH_SEARCH_LIST } from '../../constants/path';
import useDebounceValue from '../../customHooks/useDebouncedValue';
import MaginifyingGlassIcon from '../../icons/MagnifyingGlassIcon';
import { createDetailQuery } from '../../utils/createQuery';
import { getLocalStorage, setLocalStorage } from '../../utils/localStorage';
import AutoCompletedList from './AutoCompletedList';
import MoonLoader from './MoonLoader';
import MoonLoader from '../MoonLoader';
import RecentKeywordsList from './RecentKeywordsList';
import IconButton from '../IconButton';

enum DROPDOWN_TYPE {
AUTO_COMPLETE = 'AUTO_COMPLETE',
Expand Down Expand Up @@ -83,6 +85,11 @@ const Search = ({ initialKeyword = '' }: SearchProps) => {
return result;
}, []);

// 논문 상세정보 페이지로 이동
const goToDetailPage = (doi: string) => {
navigate(createDetailQuery(doi));
};

const handleInputChange = (e: ChangeEvent) => {
const target = e.target as HTMLInputElement;
setKeyword(target.value);
Expand Down Expand Up @@ -120,8 +127,7 @@ const Search = ({ initialKeyword = '' }: SearchProps) => {
// hover된 항목으로 검색
switch (dropdownType) {
case DROPDOWN_TYPE.AUTO_COMPLETE:
// Todo : 상세정보 api 호출
console.log('상세정보', autoCompletedItems?.[hoverdIndex].doi);
autoCompletedItems && goToDetailPage(autoCompletedItems?.[hoverdIndex].doi);
break;
case DROPDOWN_TYPE.RECENT_KEYWORDS:
handleSearchButtonClick(recentKeywords[hoverdIndex]);
Expand Down Expand Up @@ -156,6 +162,7 @@ const Search = ({ initialKeyword = '' }: SearchProps) => {
keyword={keyword}
hoverdIndex={hoverdIndex}
setHoveredIndex={setHoveredIndex}
handleMouseDown={goToDetailPage}
/>
),
[DROPDOWN_TYPE.RECENT_KEYWORDS]: (
Expand Down Expand Up @@ -188,9 +195,7 @@ const Search = ({ initialKeyword = '' }: SearchProps) => {
onBlur={handleInputBlur}
onKeyDown={handleInputKeyDown}
/>
<SearchButton type="button" onClick={() => handleSearchButtonClick(keyword)}>
<MaginifyingGlassIcon />
</SearchButton>
<IconButton icon={<MaginifyingGlassIcon />} onClick={() => handleSearchButtonClick(keyword)} />
</SearchBar>
<DropdownContainer>{renderDropdownContent(dropdownType)}</DropdownContainer>
</SearchBox>
Expand Down Expand Up @@ -241,11 +246,6 @@ const SearchInput = styled.input`
}
`;

const SearchButton = styled.button`
background-color: transparent;
cursor: pointer;
`;

const DropdownContainer = styled.div`
width: 100%;
overflow-y: auto;
Expand Down
4 changes: 0 additions & 4 deletions frontend/src/constants/path.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
export const PATH_MAIN = '/';
export const PATH_SEARCH_LIST = '/search-list';
export const PATH_DETAIL = '/detail';

export const createSearchQuery = (keyword: string) => {
return `${PATH_SEARCH_LIST}?keyword=${keyword}&page=1&rows=20`;
};
16 changes: 13 additions & 3 deletions frontend/src/icons/LogoIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
const LogoIcon = () => {
interface IProps {
height?: string;
width?: string;
}

const LogoIcon = ({ height, width }: IProps) => {
return (
<svg
version="1.0"
xmlns="http://www.w3.org/2000/svg"
width="30pt"
height="30pt"
width={width}
height={height}
viewBox="0 0 284 300"
preserveAspectRatio="xMidYMid meet"
>
Expand Down Expand Up @@ -63,4 +68,9 @@ const LogoIcon = () => {
);
};

LogoIcon.defaultProps = {
width: '40',
height: '40',
};

export default LogoIcon;
12 changes: 12 additions & 0 deletions frontend/src/icons/PreviousButtonIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const PreviousButtonIcon = () => {
return (
<svg width="20" height="20" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M2.69531 11.3965C1.88151 12.0068 1.88151 12.998 2.69531 13.6084L15.1953 22.9834C16.0091 23.5938 17.3307 23.5938 18.1445 22.9834C18.9583 22.373 18.9583 21.3818 18.1445 20.7715L7.11589 12.5L18.138 4.22852C18.9518 3.61816 18.9518 2.62695 18.138 2.0166C17.3242 1.40625 16.0026 1.40625 15.1888 2.0166L2.6888 11.3916L2.69531 11.3965Z"
fill="#ffffff"
/>
</svg>
);
};

export default PreviousButtonIcon;
2 changes: 1 addition & 1 deletion frontend/src/pages/Main/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from 'styled-components';
import Footer from '../../components/Footer';
import Search from '../../components/Search';
import Search from '../../components/search/Search';
import StarLayer from '../../components/StarLayer';
import { SUBTITLE, TITLE, TITLE_KOREAN } from '../../constants/main';
import LogoIcon from '../../icons/LogoIcon';
Expand Down
16 changes: 6 additions & 10 deletions frontend/src/pages/Main/components/KeywordRanking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { useQuery } from 'react-query';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import Api from '../../../api/api';
import { createSearchQuery } from '../../../constants/path';
import IconButton from '../../../components/IconButton';
import DropdownIcon from '../../../icons/DropdownIcon';
import DropDownReverseIcon from '../../../icons/DropdownReverseIcon';
import { createSearchQuery } from '../../../utils/createQuery';
import RankingSlide from './RankingSlide';

interface IRankingData {
Expand Down Expand Up @@ -42,9 +43,10 @@ const KeywordRanking = () => {
<RankingContent onClick={handleRankingClick}>
{!isLoading && (rankingData?.length ? <RankingSlide rankingData={rankingData} /> : '데이터가 없습니다.')}
</RankingContent>
<DropdownReverseButton type="button" onClick={handleRankingClick}>
{isRankingListOpen ? <DropDownReverseIcon /> : <DropdownIcon />}
</DropdownReverseButton>
<IconButton
icon={isRankingListOpen ? <DropDownReverseIcon /> : <DropdownIcon />}
onClick={handleRankingClick}
/>
</HeaderContainer>
{isRankingListOpen && (
<>
Expand Down Expand Up @@ -115,12 +117,6 @@ const HeaderContainer = styled.div`
${({ theme }) => theme.TYPO.body_h}
`;

const DropdownReverseButton = styled.button`
margin-right: 10px;
background-color: transparent;
cursor: pointer;
`;

const HeaderDivideLine = styled.hr`
width: 1px;
height: 16px;
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/pages/Main/components/RankingSlide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ const RankingSlide = ({ rankingData }: IRankingSlideProps) => {
{newRankingData.map((data, index) => (
<SlideItem key={`${index}${data.keyword}`}>
<span>{index === dataSize - 1 ? 1 : index + 1}</span>
<span>{data.keyword.length > MAX_KEYWORD_LENGTH ? `${data.keyword.slice(0, 15)}...` : data.keyword}</span>
<span>
{data.keyword.length > MAX_KEYWORD_LENGTH
? `${data.keyword.slice(0, MAX_KEYWORD_LENGTH)}...`
: data.keyword}
</span>
</SlideItem>
))}
</Slide>
Expand Down
Loading

0 comments on commit bea4df2

Please sign in to comment.