Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[team-12] Eamon & Autumn 3주차 PR #47

Open
wants to merge 42 commits into
base: team-12
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0d99911
[#37] Feat: 서버에서 filter list 받아서 화면에 표시 (#38)
deprecated-hongbiii Jun 15, 2021
479a782
[#42] label list page & milestone Page (#43)
wade3420 Jun 17, 2021
96043c2
[#40] 이슈 상세 페이지 UI 작업 (오른쪽 사이드바 제외) (#44)
deprecated-hongbiii Jun 17, 2021
8e66fbd
[#40] Fix: new comment ui 부분 컴포넌트 이름이 중간에 바뀌어서 일단 지움
deprecated-hongbiii Jun 17, 2021
8ab9696
[#40] Style: 0번째 comment margin값 수정, 새 코멘트 ui 추가 (#45)
deprecated-hongbiii Jun 17, 2021
56b4a67
[#42] button & router (#46)
wade3420 Jun 17, 2021
2899b06
Fix: 이슈 상세 페이지 라우팅 추가, flexColum -> flexColumn 오타 수정
deprecated-hongbiii Jun 17, 2021
f3c86ce
[#50] 라벨 목록 페이지 - 서버로부터 받은 데이터를 상태에 저장하여 렌더링하도록 수정 (#53)
deprecated-hongbiii Jun 17, 2021
4ba6c56
[#52] Refactor: 코드리뷰 일부 반영, 타입선언 파일 분리, 자잘한 오타 수정 (#55)
deprecated-hongbiii Jun 18, 2021
1187874
[#73] 서버에 보내는 요청 에러 해결 (#74)
deprecated-hongbiii Jun 21, 2021
4c7a9e8
[#75] Feat: jwt 토큰 유무 체크하여 로그인 페이지 또는 이슈 목록 페이지 렌더링 (#76)
deprecated-hongbiii Jun 21, 2021
81b42f8
[#50] issueData fetch (#78)
wade3420 Jun 21, 2021
7a18dbc
[#50] 마일스톤 페이지 API 이용하여 렌더링 (#80)
deprecated-hongbiii Jun 21, 2021
4b43911
[#82] Feat: 이슈 목록에서 이슈 클릭 시 상세 페이지로 라우팅 (#90)
deprecated-hongbiii Jun 22, 2021
8e286d3
[#52] Refactor: type 중복 제거 및 정리 (#92)
deprecated-hongbiii Jun 22, 2021
ddbc978
[#51][#52][#75][#94] jwt 토큰 디코딩 (#95)
deprecated-hongbiii Jun 22, 2021
03dc60f
[#79]라벨 수정 컴포넌트 UI 작성 (#99)
wade3420 Jun 23, 2021
700d4a7
[#79] Refactor: input.tsx style 변경 (#100)
wade3420 Jun 23, 2021
5d65ff3
[Closes #79]milestone 편집컴포넌트 UI 작성 (#101)
wade3420 Jun 23, 2021
ffe871e
[#103] Feat: label 편집기능 추가 close #103 (#106)
wade3420 Jun 24, 2021
230bdae
[#108]Feature: edit milestone (#109) close issue - #108
wade3420 Jun 24, 2021
cd5ea6e
[#82] 이슈 상세 페이지 렌더링 (#110)
deprecated-hongbiii Jun 24, 2021
790e95e
[#83]Feat: 새로운 라벨 생성하기 (#112) close#83
wade3420 Jun 24, 2021
416e7e0
[#84]Feat: 마일스톤 생성 (#115)
wade3420 Jun 24, 2021
7cf1efc
[#111] 코멘트 작성 기능 (#117)
deprecated-hongbiii Jun 24, 2021
521af31
[#93][#118] 화면 렌더링 문제 해결 (#119)
deprecated-hongbiii Jun 24, 2021
b40b74a
Fix: 코멘트 작성자 === 로그인 유저일 때 편집 버튼이 안 뜨는 버그 해결
deprecated-hongbiii Jun 24, 2021
8546a31
[#81]Feature: 이슈 생성 요청 (#120)
wade3420 Jun 25, 2021
e2ca06c
Feat: 배포를 위한 oauth url 변경
wade3420 Jun 25, 2021
1c20976
chore:배포를 위한 url 수정
wade3420 Jun 28, 2021
0be6c0d
[#52] Refactor: store.ts 분리 (#123)
deprecated-hongbiii Jun 28, 2021
906efcb
chore: 배포를 위한 url 수정
wade3420 Jun 28, 2021
a02d5f1
Feature: logout (#128)
wade3420 Jun 30, 2021
3e9cd41
[#126] 코멘트 삭제 기능 (#130)
deprecated-hongbiii Jun 30, 2021
0445995
Feature: markdown (#132)
wade3420 Jul 1, 2021
6072f2d
[#126] 코멘트 편집 기능 (#134)
deprecated-hongbiii Jul 1, 2021
d79c083
[#82] Feat & Fix: 이슈 상세 페이지에 사이드바 렌더링 (#135)
deprecated-hongbiii Jul 1, 2021
a722aeb
[#82] Feat: 이슈 닫기, 다시 열기 기능 추가 (#137)
deprecated-hongbiii Jul 2, 2021
ea65d42
[#82] Feat: 이슈 삭제 기능 추가 (#139)
deprecated-hongbiii Jul 2, 2021
d8abb4a
Feature: comment markdown (#141)
wade3420 Jul 2, 2021
0214e71
[#140][#116] Fix: 버그 해결 (#143)
deprecated-hongbiii Jul 2, 2021
553b974
[#142] Style: 로그아웃 버튼 스타일링, 이슈 목록 헤더의 필터 버튼들 수정 (#144)
deprecated-hongbiii Jul 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18,650 changes: 18,626 additions & 24 deletions fe/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions fe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@types/react-router-dom": "^5.1.7",
"@types/styled-components": "^5.1.9",
"axios": "^0.21.1",
"jwt-decode": "^3.1.2",
"material-ui-popup-state": "^1.8.3",
"qs": "^6.7.0",
"react": "^17.0.2",
Expand Down
41 changes: 15 additions & 26 deletions fe/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,26 @@
import { Route, BrowserRouter, Switch } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import GlobalStyle from 'style/GlobalStyle';
import { theme } from 'style/theme';
import IssuesPage from 'pages/IssuesPage';
import LoginPage from 'pages/LoginPage';
import OAuthPage from 'pages/OAuthPage';
import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles';
import { unstable_createMuiStrictModeTheme } from '@material-ui/core/styles';
import NewIssuePage from 'pages/NewIssuePage';
import { RecoilRoot } from 'recoil';
import { Suspense } from 'react';

import Router from 'Router';
const MuiTheme = unstable_createMuiStrictModeTheme();

function App() {
return (
<MuiThemeProvider theme={MuiTheme}>
<ThemeProvider theme={theme}>
<GlobalStyle />
<BrowserRouter>
<Switch>
<Route path={['/', '/issues']} exact>
<IssuesPage />
</Route>
<Route path={'/issues/new-issue'} exact>
<NewIssuePage />
</Route>
<Route path="/login" exact>
<LoginPage />
</Route>
<Route path="/login/oauth">
<OAuthPage />
</Route>
</Switch>
</BrowserRouter>
</ThemeProvider>
</MuiThemeProvider>
<RecoilRoot>
<Suspense fallback={<div>Loading...</div>}>
<MuiThemeProvider theme={MuiTheme}>
<ThemeProvider theme={theme}>
<GlobalStyle />
<Router />
</ThemeProvider>
</MuiThemeProvider>
</Suspense>
</RecoilRoot>
);
}

Expand Down
45 changes: 45 additions & 0 deletions fe/src/Router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Route, BrowserRouter, Switch } from 'react-router-dom';
import IssuesPage from 'pages/IssuesPage';
import LoginPage from 'pages/LoginPage';
import OAuthPage from 'pages/OAuthPage';
import NewIssuePage from 'pages/NewIssuePage';
import LabelPage from 'pages/LabelPage';
import MilestoneListPage from 'pages/MilestoneListPage';
import IssueDetailPage from 'pages/IssueDetailPage';
import Header from 'components/header/Header';

const Router = () => {
return (
<BrowserRouter>
<Switch>
<Route path="/" exact>
<LoginPage />
</Route>
<Route path="/login/callback">
<OAuthPage />
</Route>
<Header />
</Switch>

<Switch>
<Route path={'/issues/new-issue'}>
<NewIssuePage />
</Route>
<Route path="/issues/:id">
<IssueDetailPage />
</Route>
<Route path="/issues">
<IssuesPage />
</Route>
<Route path="/labels" exact>
<LabelPage />
</Route>
<Route path="/milestones" exact>
<MilestoneListPage />
</Route>
</Switch>
</BrowserRouter>
);
};

export default Router;
10 changes: 10 additions & 0 deletions fe/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import axios from 'axios';
import { setInterceptors } from './interceptors';



function createInstanceWithAuth() {
const instance = axios.create();
return setInterceptors(instance);
}
export const instanceWithAuth = createInstanceWithAuth();
31 changes: 31 additions & 0 deletions fe/src/api/interceptors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { AxiosInstance } from 'axios';

export function setInterceptors(instance: AxiosInstance): AxiosInstance {
instance.interceptors.request.use(
function (config) {
const token = localStorage.getItem('jwt');
config.headers.Authorization = `Bearer ${token}`;

return config;
},
function (error) {
// Do something with request error
return Promise.reject(error);
}
);

// Add a response interceptor
instance.interceptors.response.use(
function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
},
function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
}
);
return instance;
}
14 changes: 3 additions & 11 deletions fe/src/components/Issues/IssueItem.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { Checkbox } from '@material-ui/core';
import { ReactComponent as Open } from 'icons/openIssue.svg';
import { ReactComponent as Close } from 'icons/closeIssue.svg';
import { ReactComponent as Milestone } from 'icons/openMilestone.svg';
import styled from 'styled-components';
import { IssueItemType } from 'types/issueType';
import AuthorAvatar from 'components/common/AuthorAvatar';
import IssueItemLeft from './IssueItemLeft';

const IssueItem = ({
isOpen,
id,
title,
labeList,
issueNumber,
Expand All @@ -19,14 +15,10 @@ const IssueItem = ({
return (
<StyledIssueItem>
<IssueItemLeft
{...{ title, labeList, issueNumber, createdTime, milestoneTitle }}
{...{ id, title, labeList, issueNumber, createdTime, milestoneTitle }}
/>
<IssueItemRight>
<AuthorAvatar
name={author.name}
profileImg={author.profileImg}
size="S"
/>
<AuthorAvatar profileImg={author.profileImg} size="S" />
</IssueItemRight>
</StyledIssueItem>
);
Expand Down
51 changes: 41 additions & 10 deletions fe/src/components/Issues/IssueItemLeft.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
import styled from 'styled-components';
import { IssueItemLeftPropsType } from 'types/issueType';
import { ReactComponent as Open } from 'icons/openIssue.svg';
import { ReactComponent as Close } from 'icons/closeIssue.svg';
// import { ReactComponent as Close } from 'icons/closeIssue.svg';
import { ReactComponent as Milestone } from 'icons/openMilestone.svg';
import { Checkbox } from '@material-ui/core';
import Label from 'components/common/Label';
import { useHistory } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { clickedIssueIdAtom } from 'stores/issueStore';

const IssueItemLeft = ({
id,
title,
issueNumber,
createdTime,
milestoneTitle,
labeList,
}: IssueItemLeftPropsType) => {
const history = useHistory();
const setClickedIssueId = useSetRecoilState(clickedIssueIdAtom);

const routeToIssueDetailPage = () => {
setClickedIssueId(id);
history.push(`/issues/${issueNumber}`);
};

return (
<StyledIssueItemLeft>
<IssueTitle>
<Checkbox color="primary" />
<span>
<OpenSvg />
<OpenSvg />
<span className="title" onClick={routeToIssueDetailPage}>
{title}
</span>
{labeList.length
? labeList.map((label,idx) => <Label key={idx} {...{ ...label }} />)
: null}
<Spacer />
<SelectedLables>
{labeList.length
? labeList.map((label, idx) => (
<Label key={idx} {...{ ...label }} />
))
: null}
</SelectedLables>
</IssueTitle>
<IssueSubtitle>
#{issueNumber} {createdTime} <MilestoneSvg /> {milestoneTitle}
Expand All @@ -35,14 +52,19 @@ const IssueItemLeft = ({
export default IssueItemLeft;

const StyledIssueItemLeft = styled.div`
${({ theme }) => theme.style.flexColum};
${({ theme }) => theme.style.flexColumn};
`;

const IssueTitle = styled.div`
${({ theme }) => theme.style.flexAlignItemsCenter};
`;
const IssueItemRight = styled.div`
padding-right: 1.4rem;

.title {
font-weight: ${({ theme }) => theme.fontWeight.bold};
}
.title:hover {
color: ${({ theme }) => theme.color.darkBlue};
cursor: pointer;
}
`;

const OpenSvg = styled(Open)`
Expand All @@ -53,6 +75,15 @@ const OpenSvg = styled(Open)`
margin-right: 0.2rem;
`;

const Spacer = styled.div`
width: 0.5rem;
`;

const SelectedLables = styled.div`
display: flex;
gap: 0.3rem;
`;

const MilestoneSvg = styled(Milestone)`
path {
stroke: inherit;
Expand Down
32 changes: 5 additions & 27 deletions fe/src/components/Issues/IssueList.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
import { useRecoilValue } from 'recoil';
import { issuesQuery } from 'stores/issueStore';
import styled from 'styled-components';
import { IssueItemType } from 'types/issueType';
import IssueItem from './IssueItem';

export const IssueList = () => {
const testIssueArray: IssueItemType[] = [
{
isOpen: true,
title: '이슈 제목',
labeList: [
{ title: '레이블 이름', colorCode: '#4444', textColor: 'white' },
],
issueNumber: 1,
author: { name: 'eamon', profileImg: undefined },
createdTime: '2021-06-21 12:11',
milestoneTitle: '마스터즈 코스',
},
{
isOpen: true,
title: '이슈 제목',
labeList: [
{ title: '레이블 이름', colorCode: '#009999f0', textColor: 'black' },
{ title: '레이블 이름', colorCode: '#4444', textColor: 'black' },
],
issueNumber: 2,
author: { name: 'eamon', profileImg: undefined },
createdTime: '2021-06-21 12:11',
milestoneTitle: '마스터즈 코스',
},
];
const IssuesArray = useRecoilValue(issuesQuery);

return (
<StyledIssueList>
{testIssueArray.map((issue, idx) => (
{IssuesArray.map((issue, idx) => (
<IssueItem {...issue} key={idx} />
))}
</StyledIssueList>
Expand Down
30 changes: 7 additions & 23 deletions fe/src/components/Issues/Issues.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,18 @@
import styled from 'styled-components';
import { Wrapper, Upper, Lower } from 'components/common/Table';
import IssueList from './IssueList';
import IssuesHeader from './IssuesHeader';

const Issues = () => {
return (
<StyledIssues>
<StyledIssuesHeader>
<Wrapper>
<Upper>
<IssuesHeader />
</StyledIssuesHeader>
<StyledIssuesContent>
</Upper>
<Lower>
<IssueList />
</StyledIssuesContent>
</StyledIssues>
</Lower>
</Wrapper>
);
};

export default Issues;

const StyledIssues = styled.div`
${({ theme }) => theme.style.flexColum}
box-sizing: border-box;
`;

const StyledIssuesHeader = styled.div`
${({ theme }) => theme.style.upperWrapper}
width: 100%;
box-sizing: border-box;
`;

const StyledIssuesContent = styled.div`
${({ theme }) => theme.style.lowerWrapper}
box-sizing: border-box;
`;
Loading