Skip to content

Commit

Permalink
[FE] feat/#48: 이슈 목록 페이지 필터 기능 구현 (#64)
Browse files Browse the repository at this point in the history
* feat/#48: 이슈 목록 페이지 필터 기능 구현

* feat/#48: 입력된 url를 api 스트링쿼리 형식으로 파싱하는 함수

* feat/#48: api 스트링쿼리 형식를 filter 입력 형식으로 파싱하는 함수
  • Loading branch information
qkdflrgs authored Aug 4, 2023
1 parent e018b53 commit ff048ac
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 19 deletions.
102 changes: 83 additions & 19 deletions FE/src/pages/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,48 @@ import FilterBar from "../components/FilterBar/FilterBar";
import Button from "../components/common/Button/Button";
import DropdownIndicator from "../components/DropdownIndicator/DropdownIndicator";
import IssueList from "../components/IssueList/IssueList";
import { useNavigate } from "react-router-dom";
import { useNavigate, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { ListDataProps } from "../type";
import parseFilter from "../utils/parseFilter";
import parseParam from "../utils/parseParam";

export default function MainPage() {
const navigate = useNavigate();
const { filter } = useParams();
const [data, setData] = useState<ListDataProps | null>(null);
const [filterValue, setFilterValue] = useState<string>(
filter ? filter : "isOpen=true",
);

const goAddNewIssuePage = () => {
navigate("/new");
};

const [data, setData] = useState<ListDataProps | null>(null);
const showOpenIssue = () => {
navigate("/issues/isOpen=true");
};

const showCloseIssue = () => {
navigate("/issues/isOpen=false");
};

const handleEnterFilter = () => {
navigate(`/issues/${filterValue}`);
};

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFilterValue(e.target.value);
};

useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("http://3.34.141.196/api/issues");
const response = await fetch(
filter
? `http://3.34.141.196/api/issues${parseFilter(filter)}`
: "http://3.34.141.196/api/issues",
);
if (!response.ok) {
throw new Error("데이터를 가져오는 데 실패했습니다.");
}
Expand All @@ -30,25 +56,33 @@ export default function MainPage() {
};

fetchData();
}, []);
}, [filter]);

useEffect(() => {
setFilterValue(parseParam(filter!));
}, [filter]);

return (
<Main>
<FilterSection>
<FilterBar />
<FilterBar
filterValue={filterValue}
onChange={handleInputChange}
handleEnterFilter={handleEnterFilter}
/>
<Taps>
<TapButtonWrapper>
<Button
icon={"label"}
label={"레이블"}
label={`레이블(${data && data.metadata.labelCount})`}
type={"ghost"}
size={"medium"}
width={"50%"}
onClick={() => {}}
/>
<Button
icon={"milestone"}
label={"마일스톤"}
label={`레이블(${data && data.metadata.milestoneCount})`}
type={"ghost"}
size={"medium"}
width={"50%"}
Expand All @@ -72,33 +106,37 @@ export default function MainPage() {
<IssueTap>
<Button
icon={"alertCircle"}
label={"열린 이슈"}
label={`열린 이슈(${data && data.metadata.issueOpenCount})`}
type={"ghost"}
size={"medium"}
width={"50%"}
onClick={() => {}}
onClick={showOpenIssue}
/>
<Button
icon={"archive"}
label={"닫힌 이슈"}
label={`닫힌 이슈(${data && data.metadata.issueCloseCount})`}
type={"ghost"}
size={"medium"}
width={"50%"}
onClick={() => {}}
onClick={showCloseIssue}
/>
</IssueTap>
<FilterTap>
<DropdownIndicator label={"담당자"} onClick={() => {}} />
<DropdownIndicator label={"레이블"} onClick={() => {}} />
<DropdownIndicator label={"마일스톤"} onClick={() => {}} />
<DropdownIndicator label={"작성자"} onClick={() => {}} />
<DropdownIndicator label={"담당자"} hasDropdown={true} />
<DropdownIndicator label={"레이블"} />
<DropdownIndicator label={"마일스톤"} />
<DropdownIndicator label={"작성자"} />
</FilterTap>
</TapWrapper>
</TableHeader>
<IssueContents>
{data &&
data.issues.map((issue, key) => (
<IssueList key={key} issue={issue} />
(data.issues.length !== 0 ? (
data.issues.map((issue, key) => (
<IssueList key={key} issue={issue} />
))
) : (
<EmptyList>
<EmptyContent>등록된 이슈가 없습니다</EmptyContent>
</EmptyList>
))}
</IssueContents>
</IssueTable>
Expand Down Expand Up @@ -227,3 +265,29 @@ const IssueContents = styled.ul`
border-bottom-right-radius: ${({ theme }) => theme.radius.large};
}
`;

const EmptyList = styled.li`
display: flex;
align-items: center;
padding: 0px 32px;
width: 100%;
height: 96px;
background-color: ${({ theme }) => theme.colorSystem.neutral.surface.strong};
&::after {
content: "";
position: absolute;
top: 0px;
left: 0px;
height: 1px;
width: 100%;
background-color: ${({ theme }) =>
theme.colorSystem.neutral.border.default};
}
`;

const EmptyContent = styled.span`
width: 100%;
text-align: center;
font: ${({ theme }) => theme.font.displayMedium16};
color: ${({ theme }) => theme.colorSystem.neutral.text.weak};
`;
3 changes: 3 additions & 0 deletions FE/src/utils/parseFilter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function parseFilter(value: string | undefined): string {
return value === undefined ? "" : `?${value}`.replace(/ /g, "&");
}
3 changes: 3 additions & 0 deletions FE/src/utils/parseParam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function parseParam(value: string | undefined): string {
return value === undefined ? "" : value.replace(/&/g, " ");
}

0 comments on commit ff048ac

Please sign in to comment.