Skip to content

Commit

Permalink
[FE] feat/#215: 4주차 기능 구현 (#216)
Browse files Browse the repository at this point in the history
* feat/#215: 유틸 함수 추가

* design/#215: 디자인 시스템 필터 추가

* feat/#215: 깃허브 Oauth 연결 페이지 구현

* feat/#215: 마일스톤 페이지 로딩 인디케이터 구현

* design/#215: 기본 유저 이미지 추가

* feat/#215: 추가 생성 페이지 라우터 구현

* feat/#215: 타입 추가

* refactor/#215: Alert 컴포넌트 리팩토링

* refactor/#215: Comment 컴포넌트 리팩토링

* refactor/#215: 드롭다운 컴포넌트 리팩토링

* feat/#215: 로딩 인디케이터 컴포넌트 구현

* feat/#215: 프로필 수정 페이지 구현

* feat/#215: 페이지 컴포넌트 로딩 인디케이터 적용

* refactor/#215: 4주차 컴포넌트 리팩토링

* feat/#215: 회원가입 페이지 구현

* refactor/#215: 페이지 컴포넌트 리팩토링

* feat/#215: 사이드바 아이템 컴포넌트 구현

* feat/#215: 상수 추가

* feat/#215: 로그인 사용자 context 구현

* refactor/#215: 이슈 상세페이지 리팩토링

* add/#215: 마크다운 라이브러리 추가
  • Loading branch information
qkdflrgs authored Aug 18, 2023
1 parent 7201955 commit 7db0619
Show file tree
Hide file tree
Showing 37 changed files with 6,574 additions and 1,077 deletions.
3,386 changes: 3,194 additions & 192 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 @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@uiw/react-md-editor": "^3.23.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.2",
Expand Down
Binary file added FE/public/icons/user.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 46 additions & 18 deletions FE/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,62 @@ import { lightMode, darkMode } from "./styles/DesignSystem.ts";
import { ThemeProvider, styled } from "styled-components";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import LoginPage from "./pages/LoginPage.tsx";
import Header from "./components/Header/Header.tsx";
import LabelsPage from "./pages/LabelsPage.tsx";
import MilestonesPage from "./pages/MilestonesPage.tsx";
import IssueDetail from "./pages/IssueDetail.tsx";
import JoinPage from "./pages/JoinPage.tsx";
import { OauthPage } from "./pages/OauthPage.tsx";
import { AuthProvider } from "./context/AuthContext.tsx";
import EditProfile from "./pages/EditProfilePage.tsx";

function App() {
const [theme, toggleTheme] = useDarkMode();
const themeMode = theme === "light" ? lightMode : darkMode;

return (
<ThemeProvider theme={themeMode}>
<BrowserRouter>
<Page>
<Header toggleTheme={toggleTheme} />
<Routes>
<Route path="/issues" element={<MainPage />}></Route>
<Route path="" element={<LoginPage />}></Route>
<Route path="/new" element={<AddIssuePage />}></Route>
<Route path="/labels" element={<LabelsPage />}></Route>
<Route
path="/milestones/:state"
element={<MilestonesPage />}
></Route>
<Route path="/issues/:filter" element={<MainPage />}></Route>
<Route path="/detail/:id" element={<IssueDetail />}></Route>
</Routes>
</Page>
</BrowserRouter>
<AuthProvider>
<BrowserRouter>
<Page>
<Routes>
<Route
path="/issues"
element={<MainPage toggleTheme={toggleTheme} />}
></Route>
<Route
path="/new"
element={<AddIssuePage toggleTheme={toggleTheme} />}
></Route>
<Route
path="/labels"
element={<LabelsPage toggleTheme={toggleTheme} />}
></Route>
<Route
path="/redirect/oauth"
element={<OauthPage toggleTheme={toggleTheme} />}
></Route>
<Route
path="/milestones/:state"
element={<MilestonesPage toggleTheme={toggleTheme} />}
></Route>
<Route
path="/issues/:filter"
element={<MainPage toggleTheme={toggleTheme} />}
></Route>
<Route
path="/detail/:id"
element={<IssueDetail toggleTheme={toggleTheme} />}
></Route>
<Route
path="/profile"
element={<EditProfile toggleTheme={toggleTheme} />}
></Route>
<Route path="" element={<LoginPage />}></Route>
<Route path="/join" element={<JoinPage />}></Route>
</Routes>
</Page>
</BrowserRouter>
</AuthProvider>
</ThemeProvider>
);
}
Expand Down
52 changes: 35 additions & 17 deletions FE/src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,40 @@ export default function Alert({
onClickRightButton,
}: Props) {
return (
<Container>
<AlertContent>{content}</AlertContent>
<ButtonTap>
<Button
type={"outline"}
label={leftButtonLabel}
width={"176px"}
onClick={onClickLeftButton}
/>
<Button
label={rightButtonLabel}
width={"176px"}
onClick={onClickRightButton}
/>
</ButtonTap>
</Container>
<Dim>
<Container>
<AlertContent>{content}</AlertContent>
<ButtonTap>
<Button
type={"outline"}
label={leftButtonLabel}
width={"176px"}
onClick={onClickLeftButton}
/>
<Button
label={rightButtonLabel}
width={"176px"}
onClick={onClickRightButton}
/>
</ButtonTap>
</Container>
</Dim>
);
}

const Dim = styled.div`
position: absolute;
top: 0px;
left: 0px;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
z-index: 1000;
background-color: rgba(16, 20, 26, 0.4);
`;

const Container = styled.div`
display: flex;
flex-direction: column;
Expand All @@ -50,7 +65,10 @@ const Container = styled.div`
box-shadow: ${({ theme }) => theme.dropShadow.lightMode};
`;

const AlertContent = styled.p``;
const AlertContent = styled.p`
font: ${({ theme }) => theme.font.displayMedium16};
color: ${({ theme }) => theme.colorSystem.neutral.text.default};
`;

const ButtonTap = styled.div`
width: 100%;
Expand Down
9 changes: 7 additions & 2 deletions FE/src/components/Comment/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { styled } from "styled-components";
import { AssigneesList } from "../../type";
import UserProfileButton from "../UserProfileButton/UserProfileButton";
import { calculateTime } from "../../utils/calculateTime";
import Button from "../common/Button/Button";
import { useEffect, useState } from "react";
Expand Down Expand Up @@ -122,7 +121,7 @@ export default function Comment({
<CommentWrapper $isEdit={isEdit}>
<Header>
<Info>
<UserProfileButton src={author.profileImageUrl} />
<UserProfileImg src={author.profileImageUrl} />
<UserName>{author.nickname}</UserName>
<Time>{calculateTime(createAt)}</Time>
</Info>
Expand Down Expand Up @@ -207,6 +206,12 @@ const Header = styled.div`
border-top-right-radius: inherit;
`;

const UserProfileImg = styled.img`
width: 32px;
height: 32px;
border-radius: ${({ theme }) => theme.radius.half};
`;

const Info = styled.div`
display: flex;
gap: 8px;
Expand Down
81 changes: 11 additions & 70 deletions FE/src/components/DropdownIndicator/DropdownIndicator.tsx
Original file line number Diff line number Diff line change
@@ -1,89 +1,32 @@
import { useState } from "react";
import { styled } from "styled-components";
import DropdownPanel from "../DropdownPanel/DropdownPanel";

type Props = {
type?: "filter" | "assignees" | "labels" | "milestones" | "authors" | "none";
icon?: string;
label: string;
padding?: string;
width?: string;
height?: string;
dropdownTop?: string;
dropdownLeft?: string;
onClick(): void;
};

export default function DropdownIndicator({
type = "filter",
icon = "chevronDown",
label,
padding = "4px 0px",
width = "80px",
height = "32px",
dropdownTop = "0px",
dropdownLeft = "0px",
onClick,
}: Props) {
const [openDropdown, setOpenDropdown] = useState<boolean>(false);

const openDropdownPanel = () => {
setOpenDropdown(true);
};

const closeDropdownPanel = () => {
setOpenDropdown(false);
};

return (
<Container>
<IndicatorButton
$padding={padding}
$width={width}
$height={height}
onClick={openDropdownPanel}
>
<IndicatorLabel>{label}</IndicatorLabel>
<IndicatorIcon src={`/icons/${icon}.svg`} />
</IndicatorButton>
{openDropdown && type === "filter" && (
<DropdownPanel
top={dropdownTop}
left={dropdownLeft}
closeDropdown={closeDropdownPanel}
/>
)}
{openDropdown && type === "assignees" && (
<DropdownPanel
type={"assignees"}
top={"40px"}
left={"0px"}
closeDropdown={closeDropdownPanel}
/>
)}
{openDropdown && type === "labels" && (
<DropdownPanel
type={"labels"}
top={"40px"}
left={"112px"}
closeDropdown={closeDropdownPanel}
/>
)}
{openDropdown && type === "milestones" && (
<DropdownPanel
type={"milestones"}
top={"40px"}
left={"180px"}
closeDropdown={closeDropdownPanel}
/>
)}
{openDropdown && type === "authors" && (
<DropdownPanel
type={"authors"}
top={"40px"}
left={"200px"}
closeDropdown={closeDropdownPanel}
/>
)}
</Container>
<IndicatorButton
$padding={padding}
$width={width}
$height={height}
onClick={onClick}
>
<IndicatorLabel>{label}</IndicatorLabel>
<IndicatorIcon src={`/icons/${icon}.svg`} />
</IndicatorButton>
);
}

Expand All @@ -109,8 +52,6 @@ const IndicatorButton = styled.button<{
}
`;

const Container = styled.div``;

const IndicatorLabel = styled.span`
font: ${({ theme }) => theme.font.availableMedium16};
color: ${({ theme }) => theme.colorSystem.neutral.text.default};
Expand Down
67 changes: 59 additions & 8 deletions FE/src/components/DropdownPanel/DropdownItem.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import { useState } from "react";
import { useParams } from "react-router-dom";
import { styled } from "styled-components";
import UserProfileButton from "../UserProfileButton/UserProfileButton";

type Props = {
userImg?: string;
imgSource?: string;
color?: string;
itemName: string;
criteria?: string;
value?: string;
checkbox?: boolean;
onClick(): void;
};

export default function DropdownItem({
userImg = "",
imgSource = "",
color = "",
itemName,
criteria,
value,
checkbox = true,
onClick,
}: Props) {
const { filter } = useParams();
const [isSelect] = useState<boolean>(
criteria ? criteria === value : filter === value,
);
return (
<Container onClick={onClick}>
<Info>
{userImg && <UserProfileButton src={userImg} size={"small"} />}
<Label>{itemName}</Label>
{color && <ColorIcon $color={color}></ColorIcon>}
{imgSource && <ImgIcon src={imgSource} />}
<Label $isSelect={isSelect}>{itemName}</Label>
</Info>
<Checkbox type={"checkbox"}></Checkbox>
{checkbox && <Checkbox type={"checkbox"} checked={isSelect}></Checkbox>}
</Container>
);
}
Expand All @@ -36,9 +50,46 @@ const Container = styled.button`

const Info = styled.div`
display: flex;
align-items: center;
gap: 8px;
`;

const Label = styled.label``;
const ColorIcon = styled.div<{ $color: string }>`
width: 20px;
height: 20px;
border-radius: ${({ theme }) => theme.radius.half};
background-color: ${({ $color }) => $color};
border: ${({ $color, theme }) =>
`${theme.border.default} ${
$color === "#FEFEFE" ? theme.colorSystem.neutral.text.weak : "none"
}`};
`;

const ImgIcon = styled.img`
width: 20px;
height: 20px;
border-radius: ${({ theme }) => theme.radius.half};
`;

const Label = styled.span<{ $isSelect: boolean }>`
font: ${({ $isSelect, theme }) =>
$isSelect ? theme.font.selectedBold16 : theme.font.availableMedium16};
color: ${({ $isSelect, theme }) =>
$isSelect
? theme.colorSystem.neutral.text.strong
: theme.colorSystem.neutral.text.weak};
`;

const Checkbox = styled.input``;
const Checkbox = styled.input`
cursor: pointer;
appearance: none;
width: 16px;
height: 16px;
background-image: url("/icons/checkOffCircle.svg");
&:checked {
border-color: transparent;
background-image: url("/icons/checkOnCircle.svg");
background-size: 100% 100%;
background-repeat: no-repeat;
}
`;
Loading

0 comments on commit 7db0619

Please sign in to comment.