Skip to content
This repository has been archived by the owner on Jul 8, 2024. It is now read-only.

Commit

Permalink
release: 1.0.7 배포 (#108)
Browse files Browse the repository at this point in the history
* refactor(types/profile): profile tab에서 사용되는 타입들을 각 파일마다 분리

* feat(*): 나의 풀이 Tab 문제 유형 select 기능 추가
  • Loading branch information
dev-redo authored Nov 24, 2022
1 parent 97dc901 commit 695b262
Show file tree
Hide file tree
Showing 16 changed files with 326 additions and 217 deletions.
25 changes: 24 additions & 1 deletion src/components/select/CheckOption.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from 'styled-components';
import CloseBoxOnOutside from '@src/components/section/CloseBoxOnOutside';
import DropdownIcon from '@assets/icons/Dropdown.svg';
import '@src/styles/font.css';
import { CheckOptionStyle } from '@src/styles/global';

interface CheckOptionProps {
isOpen: boolean;
Expand All @@ -23,4 +23,27 @@ const CheckOption = ({ isOpen, value, onModalChange }: CheckOptionProps) => {
);
};

const CheckOptionStyle = styled.div<{ isOpen: boolean }>`
display: flex;
align-items: center;
z-index: 1;
cursor: pointer;
font-size: 1rem;
font-family: 'Nanum Gothic', sans-serif;
font-weight: 400;
color: ${({ theme }) => theme.color.darkGrey};
background-color: ${({ isOpen, theme }) =>
isOpen ? theme.color.grayishWhite : theme.color.grey};
margin-bottom: 1rem;
padding: 0.8rem 1.2rem;
border-radius: 0.2rem;
outline: ${({ isOpen, theme }) => isOpen && `${theme.color.grey} 2px solid`};
&:hover {
background-color: ${({ theme }) => theme.color.grayishWhite};
}
span {
margin-right: 0.4rem;
}
`;

export default CheckOption;
23 changes: 23 additions & 0 deletions src/components/select/PartTitleSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { useRecoilState } from 'recoil';
import Select from '.';
import CheckOption from './CheckOption';
import { problemTitleOption } from '@src/store/select';
import { PartTitleSelectProps } from '@src/types/select';
import '@src/styles/font.css';

const PartTitleSelect = ({ partTitleList }: PartTitleSelectProps) => {
const [isOpen, setIsOpen] = React.useState(false);
const [selected, setSelected] = useRecoilState(problemTitleOption);

return (
<Select
isOpen={isOpen}
trigger={<CheckOption isOpen={isOpen} value={selected} onModalChange={setIsOpen} />}
options={partTitleList}
onChangeDropdown={setSelected}
/>
);
};

export default PartTitleSelect;
14 changes: 9 additions & 5 deletions src/components/select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ Dropdown.Menu = ({ isOpen, children }: MenuProps) => {
};

Dropdown.Item = ({ onChangeDropdown, filterState, children }: ItemProps) => {
const optionName = filterState[children];
const optionName = filterState === undefined ? children : filterState[children];

const onPreventEvent = (event: React.MouseEvent) => event.preventDefault();
const onChangeOption = () => onChangeDropdown(children);

return (
<ItemStyle type="button" value={children} onMouseDown={onPreventEvent} onClick={onChangeOption}>
<ItemStyle value={children} onMouseDown={onPreventEvent} onClick={onChangeOption}>
{optionName}
</ItemStyle>
);
Expand All @@ -51,15 +51,16 @@ const ContainerStyle = styled.div`
display: flex;
flex-direction: column;
align-items: flex-end;
position: relative;
`;

const MenuStyle = styled.div<{ isOpen: boolean }>`
const MenuStyle = styled.ul<{ isOpen: boolean }>`
visibility: ${({ isOpen }) => (isOpen ? 'visible' : 'hidden')};
display: flex;
flex-direction: column;
position: absolute;
z-index: 2;
top: 8rem;
top: 3rem;
padding: 0.5rem 0rem;
font-size: 1rem;
color: ${({ theme }) => theme.color.darkGrey};
Expand All @@ -69,15 +70,18 @@ const MenuStyle = styled.div<{ isOpen: boolean }>`
border-radius: 0.25rem;
line-height: 1.6;
background-color: ${({ theme }) => theme.color.white};
max-height: 18.5rem;
overflow: auto;
`;

const ItemStyle = styled.button`
padding: 0.3rem 0.875rem;
padding: 0.5rem 1rem;
font-size: 1rem;
font-family: 'Nanum Gothic', sans-serif;
font-weight: 400;
color: ${({ theme }) => theme.color.darkGrey};
background-color: transparent;
display: flex;
`;

export default Select;
68 changes: 37 additions & 31 deletions src/pages/newTab/profile/Problems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,43 @@ import React from 'react';
import styled, { css } from 'styled-components';
import { uid } from 'react-uid';
import { useRecoilState } from 'recoil';

import PartTitleSelect from '@src/components/select/PartTitleSelect';
import Pagination from '@src/components/section/Pagination';

import { sortOption } from '@src/store/profile';
import { BoxStyle } from '@src/styles/global';
import { ContentHeaderInfoStyle } from '@src/styles/global';
import Book from '@assets/icons/Book.svg';
import ArrowUp from '@assets/icons/ArrowUp.svg';
import ArrowDown from '@assets/icons/ArrowDown.svg';
import { sortOption } from '@src/store/profile';

import { levelsColor } from '@src/constants/level';
import { PROBLEM_LIST, SORT_LIST, SORT_TYPE } from '@src/constants/profile';
import '@src/styles/font.css';
import { SOLVING_PROBLEM_URL as BASE_URL } from '@src/constants/url';
import {
ProblemType,
SolvedProblemProps,
SelectNameType,
SortProps,
SortItemProps,
SortType,
SortItemType,
ProblemTableProps,
SolvedProblemType,
} from '@src/types/profile';
import Pagination from '@src/components/section/Pagination';
import { levelsColor } from '@src/constants/level';
import { SOLVING_PROBLEM_URL as BASE_URL } from '@src/constants/url';
ContentProps,
} from '@src/types/profile/profile-problems';
import Book from '@assets/icons/Book.svg';
import ArrowUp from '@assets/icons/ArrowUp.svg';
import ArrowDown from '@assets/icons/ArrowDown.svg';
import NoContent from '@assets/images/noContent.png';
import '@src/styles/font.css';

export default function Problems({ solvedProblems }: SolvedProblemProps) {
export default function Problems({ solvedProblems, partTitleList }: SolvedProblemProps) {
const [pageIdx, setPageIdx] = React.useState(0);
const limit = 10;
const offset = pageIdx * limit;

return (
<BoxStyle>
<Problems.Header />
<Problems.Sort onChangePageIdx={setPageIdx} />
<Problems.Sort onChangePageIdx={setPageIdx} partTitleList={partTitleList} />
<Problems.Content solvedProblems={solvedProblems}>
<Problems.ItemList start={offset} end={offset + limit} solvedProblems={solvedProblems} />
<Pagination
Expand All @@ -56,20 +62,18 @@ Problems.Header = () => {
);
};

Problems.Sort = ({ onChangePageIdx }: { onChangePageIdx: (page: number) => void }) => (
<SortStyle>
<SortTextItemStyle>정렬 —</SortTextItemStyle>
{SORT_LIST.map((item, idx) => (
<Problems.SortItem key={uid(idx)} item={item} onChangePageIdx={onChangePageIdx} />
))}
</SortStyle>
Problems.Sort = ({ onChangePageIdx, partTitleList }: SortProps) => (
<SortContainerStyle>
<SortStyle>
<SortTextItemStyle>정렬 —</SortTextItemStyle>
{SORT_LIST.map((item, idx) => (
<Problems.SortItem key={uid(idx)} item={item} onChangePageIdx={onChangePageIdx} />
))}
</SortStyle>
<PartTitleSelect partTitleList={partTitleList} />
</SortContainerStyle>
);

type SortItemProps = {
item: SelectNameType;
onChangePageIdx: (page: number) => void;
};

Problems.SortItem = ({ item, onChangePageIdx }: SortItemProps) => {
const [sortType, setSortType] = useRecoilState(sortOption);
const itemName = (SORT_TYPE as SortItemType)[item];
Expand Down Expand Up @@ -105,11 +109,6 @@ Problems.SortItem = ({ item, onChangePageIdx }: SortItemProps) => {
);
};

type ContentProps = {
children: JSX.Element | JSX.Element[];
solvedProblems: SolvedProblemType;
};

Problems.Content = ({ children, solvedProblems }: ContentProps) => {
if (solvedProblems.length === 0) {
return (
Expand Down Expand Up @@ -183,17 +182,24 @@ const HeaderStyle = styled.div`
gap: 0.5rem;
`;

const SortStyle = styled.div`
const SortContainerStyle = styled.div`
white-space: nowrap;
height: 3rem;
vertical-align: middle;
display: flex;
align-items: center;
justify-content: space-between;
align-items: baseline;
font-family: 'Noto Sans KR', sans-serif;
font-weight: 500;
margin: 1rem 0;
`;

const SortStyle = styled.ul`
display: flex;
justify-content: center;
align-items: center;
`;

const SortItemStyle = styled.span`
text-align: left;
display: inline-block;
Expand Down
17 changes: 7 additions & 10 deletions src/pages/newTab/profile/ProfileTab.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import styled from 'styled-components';
import { useRecoilState } from 'recoil';
import { uid } from 'react-uid';
import LogoWhite from '@assets/images/logo-white.png';
import 'chart.js/auto';
import { NavType } from '@src/types/profile';
import '@src/styles/font.css';

import { navOption } from '@src/store/profile';
import { NavType, ContentType } from '@src/types/profile/profile-tab';
import { Children } from '@src/types/global';
import { LoaderStyle } from '@src/styles/global';
import { GNBStyle } from '@src/styles/global';
import { NAV_LIST, NAV_TYPE } from '@src/constants/profile';
import { navOption } from '@src/store/profile';

import LogoWhite from '@assets/images/logo-white.png';
import Spinner from '@assets/icons/BlackSpinner.svg';
import { LoaderStyle } from '@src/styles/global';
import { Children } from '@src/types/global';

export default function ProfileTab({ children }: Children) {
return <ContainerStyle>{children}</ContainerStyle>;
Expand Down Expand Up @@ -45,11 +47,6 @@ ProfileTab.NavItem = ({ item }: { item: string }) => {
);
};

type ContentType = {
children: React.ReactNode;
isLoaded: boolean;
isLoggedIn: boolean;
};
ProfileTab.Content = ({ children, isLoaded, isLoggedIn }: ContentType) => {
if (isLoggedIn === false) {
return (
Expand Down
19 changes: 14 additions & 5 deletions src/pages/newTab/profile/Statistics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@ import styled from 'styled-components';
import { uid } from 'react-uid';
import 'chart.js/auto';
import { Doughnut } from 'react-chartjs-2';
import { levels, levelsColor } from '@src/constants/level';
import Chart from '@assets/icons/Chart.svg';
import { ProblemCntType, DoughnutType, ChartInfo, ChartInfoList } from '@src/types/profile';
import '@src/styles/font.css';
import { BoxStyle, BoldTextStyle } from '@src/styles/global';

import { getPercentile } from '@src/utils/getPercentile';

import { BoxStyle, BoldTextStyle } from '@src/styles/global';
import { Children } from '@src/types/global';
import { ContentHeaderInfoStyle } from '@src/styles/global';
import { STATIST_HEAD } from '@src/constants/profile';
import { levels, levelsColor } from '@src/constants/level';

import {
ProblemCntType,
DoughnutType,
ChartInfo,
ChartInfoList,
} from '@src/types/profile/profile-statistics';

import Chart from '@assets/icons/Chart.svg';
import '@src/styles/font.css';

interface StatisticsType {
problemCnt: ProblemCntType;
Expand Down
Loading

0 comments on commit 695b262

Please sign in to comment.