-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: (#54) 투표 통계 mockData 생성 * feat: (#54) 투표 통계 관련 type, interface 생성 - 나이대 type - 투표통계 총결과 interface * feat: (#54) 그래프 공통 스타일 생성 * feat: (#54) 막대 하나 그래프 구현 * test: (#54) 막대 하나 그래프 사이즈별 테스트 구현 * feat: (#54) 막대 두개 그래프 구현 * test: (#54) 막대 두개 그래프 사이즈별 테스트 구현 * design: (#54) 그래프 공통 스타일 수정 * feat: (#54) 라디오를 포함한 투표 통계 결과 그래프 컴포넌트 구현 * test: (#54) 라디오를 포함한 투표 통계 결과 그래프 컴포넌트 테스트 구현 * refactor: 라디오를 포함한 투표 통계결과 그래프 컴포넌트명/폴더명 변경 - VoteResult -> VoteStatistics - 수정이유: 투표결과 데이터 타입명과 중복 * style: (#54) styled component 파일 컨벤션에 맞춰 순서 수정 * refactor: (#54) 통계 컴포넌트 타입/인터베이스 오타 수정 * refactor: (#54) 그래프 스타일 상수화하여 코드 정리 * refactor: (#54) 공통된 그래프 프롭스 interface 리팩토링 * refactor: 투표 통계 나이대 속성 type 리팩토링 - 투표 나이대 상수화 - 투표 나이대 상수에서 나이대 type 추출 - VoteDetailResult를 value로 가지는 투표 나이대 객체 type 생성 - 기존 voteResult interface에 투표 나이대 객체 type 연결 * refactor: (#54) 몇몇 컴포넌트 반응형 웹 기준 상수화 적용 - 게시글, 선택지, 투표 통계 컴포넌트 * refactor: (#54) 몇몇 컴포넌트 반응형 웹 기준 상수화 재적용 - 게시글, 선택지, 투표 통계 컴포넌트
- Loading branch information
Showing
17 changed files
with
423 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
import { styled } from 'styled-components'; | ||
|
||
import { theme } from '@styles/theme'; | ||
|
||
export const Button = styled.button` | ||
width: 80px; | ||
color: ${theme.color.white}; | ||
background: ${theme.color.primary}; | ||
color: red; | ||
background: black; | ||
font-size: 1rem; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { styled } from 'styled-components'; | ||
|
||
import { Size } from '@components/common/AddButton/type'; | ||
|
||
import { theme } from '@styles/theme'; | ||
|
||
const size: { [key in Size]: { height: string; linePositionTop: string } } = { | ||
sm: { height: '200px', linePositionTop: '165px' }, | ||
md: { height: '230px', linePositionTop: '194px' }, | ||
lg: { height: '260px', linePositionTop: '224px' }, | ||
}; | ||
|
||
export const GraphContainer = styled.div<{ $size: Size }>` | ||
display: flex; | ||
height: ${props => `${size[props.$size].height}`}; | ||
position: relative; | ||
font-size: 1.2rem; | ||
@media (min-width: ${theme.breakpoint.sm}) { | ||
font-size: 1.4rem; | ||
} | ||
`; | ||
|
||
export const Line = styled.div<{ $size: Size }>` | ||
width: 100%; | ||
border-bottom: 2px solid black; | ||
position: absolute; | ||
top: ${props => `${size[props.$size].linePositionTop}`}; | ||
`; |
24 changes: 24 additions & 0 deletions
24
frontend/src/components/VoteStatistics/OneLineGraph/OneLineGraph.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import { mockVoteResult } from '../mockData'; | ||
|
||
import OneLineGraph from '.'; | ||
|
||
const meta: Meta<typeof OneLineGraph> = { | ||
component: OneLineGraph, | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof OneLineGraph>; | ||
|
||
export const SizeSm: Story = { | ||
render: () => <OneLineGraph size="sm" voteResult={mockVoteResult} />, | ||
}; | ||
|
||
export const SizeMd: Story = { | ||
render: () => <OneLineGraph size="md" voteResult={mockVoteResult} />, | ||
}; | ||
|
||
export const SizeLg: Story = { | ||
render: () => <OneLineGraph size="lg" voteResult={mockVoteResult} />, | ||
}; |
28 changes: 28 additions & 0 deletions
28
frontend/src/components/VoteStatistics/OneLineGraph/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import * as GS from '../GraphStyle'; | ||
import { AGE_OPTION, GraphProps } from '../type'; | ||
|
||
import * as S from './style'; | ||
|
||
export default function OneLineGraph({ voteResult, size }: GraphProps) { | ||
const maxVoteAmount = Math.max( | ||
...Object.values(voteResult.age).map(voteResult => voteResult.total) | ||
); | ||
|
||
return ( | ||
<GS.GraphContainer $size={size}> | ||
<GS.Line $size={size} /> | ||
{AGE_OPTION.map(option => { | ||
const voteResultFilteredByAge = voteResult.age[option]; | ||
const amount = Math.floor((voteResultFilteredByAge.total / maxVoteAmount) * 100); | ||
|
||
return ( | ||
<S.OptionContainer $size={size}> | ||
<span aria-label="투표한 인원">{voteResultFilteredByAge.total}</span> | ||
<S.OptionLength $amount={amount} /> | ||
<span aria-label="투표한 나이대">{voteResultFilteredByAge.name}</span> | ||
</S.OptionContainer> | ||
); | ||
})} | ||
</GS.GraphContainer> | ||
); | ||
} |
34 changes: 34 additions & 0 deletions
34
frontend/src/components/VoteStatistics/OneLineGraph/style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { styled } from 'styled-components'; | ||
|
||
import { Size } from '@components/common/AddButton/type'; | ||
|
||
import { theme } from '@styles/theme'; | ||
|
||
export const OptionContainer = styled.div<{ $size: Size }>` | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-end; | ||
align-items: center; | ||
gap: 5px; | ||
width: ${props => (props.$size === 'sm' ? '30px' : props.$size === 'md' ? '40px' : '50px')}; | ||
& > :last-child { | ||
height: 30px; | ||
text-align: center; | ||
word-break: keep-all; | ||
} | ||
@media (min-width: ${theme.breakpoint.sm}) { | ||
width: ${props => (props.$size === 'sm' ? '40px' : props.$size === 'md' ? '50px' : '60px')}; | ||
} | ||
`; | ||
|
||
export const OptionLength = styled.div<{ $amount: number }>` | ||
height: ${props => `${props.$amount * 0.8}%`}; | ||
width: 40%; | ||
border-radius: 5px 5px 0 0; | ||
background-color: #f27676; | ||
`; |
24 changes: 24 additions & 0 deletions
24
frontend/src/components/VoteStatistics/TwoLineGraph/TwoLineGraph.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import { mockVoteResult } from '../mockData'; | ||
|
||
import TwoLineGraph from '.'; | ||
|
||
const meta: Meta<typeof TwoLineGraph> = { | ||
component: TwoLineGraph, | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof TwoLineGraph>; | ||
|
||
export const SizeSm: Story = { | ||
render: () => <TwoLineGraph size="sm" voteResult={mockVoteResult} />, | ||
}; | ||
|
||
export const SizeMd: Story = { | ||
render: () => <TwoLineGraph size="md" voteResult={mockVoteResult} />, | ||
}; | ||
|
||
export const SizeLg: Story = { | ||
render: () => <TwoLineGraph size="lg" voteResult={mockVoteResult} />, | ||
}; |
41 changes: 41 additions & 0 deletions
41
frontend/src/components/VoteStatistics/TwoLineGraph/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import * as GS from '../GraphStyle'; | ||
import { AGE_OPTION, GraphProps } from '../type'; | ||
|
||
import * as S from './style'; | ||
|
||
export default function TwoLineGraph({ voteResult, size }: GraphProps) { | ||
const maxVoteAmount = Math.max( | ||
...Object.values(voteResult.age).map(voteResult => Math.max(voteResult.female, voteResult.male)) | ||
); | ||
|
||
return ( | ||
<GS.GraphContainer $size={size}> | ||
<GS.Line $size={size} /> | ||
{AGE_OPTION.map(option => { | ||
const voteResultFilteredByAge = voteResult.age[option]; | ||
|
||
return ( | ||
<S.OptionContainer $size={size}> | ||
<S.DataWrapper> | ||
<S.OptionLengthWrapper $gender="female"> | ||
<span aria-label="투표한 여자수">{voteResultFilteredByAge.female}</span> | ||
<S.OptionLength | ||
$amount={(voteResultFilteredByAge.female / maxVoteAmount) * 100} | ||
$gender="female" | ||
/> | ||
</S.OptionLengthWrapper> | ||
<S.OptionLengthWrapper $gender="male"> | ||
<span aria-label="투표한 남자수">{voteResultFilteredByAge.male}</span> | ||
<S.OptionLength | ||
$amount={(voteResultFilteredByAge.male / maxVoteAmount) * 100} | ||
$gender="male" | ||
/> | ||
</S.OptionLengthWrapper> | ||
</S.DataWrapper> | ||
<span aria-label="투표한 나이대">{voteResultFilteredByAge.name}</span> | ||
</S.OptionContainer> | ||
); | ||
})} | ||
</GS.GraphContainer> | ||
); | ||
} |
63 changes: 63 additions & 0 deletions
63
frontend/src/components/VoteStatistics/TwoLineGraph/style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { styled } from 'styled-components'; | ||
|
||
import { Size } from '@components/common/AddButton/type'; | ||
|
||
import { theme } from '@styles/theme'; | ||
|
||
export const OptionContainer = styled.div<{ $size: Size }>` | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-end; | ||
align-items: center; | ||
gap: 5px; | ||
width: ${props => (props.$size === 'sm' ? '30px' : props.$size === 'md' ? '40px' : '50px')}; | ||
& > :last-child { | ||
height: 30px; | ||
text-align: center; | ||
word-break: keep-all; | ||
} | ||
@media (min-width: ${theme.breakpoint.sm}) { | ||
width: ${props => (props.$size === 'sm' ? '40px' : props.$size === 'md' ? '50px' : '60px')}; | ||
} | ||
`; | ||
|
||
export const DataWrapper = styled.div` | ||
display: flex; | ||
justify-content: center; | ||
height: 90%; | ||
width: 50px; | ||
@media (min-width: ${theme.breakpoint.sm}) { | ||
width: 60px; | ||
} | ||
`; | ||
|
||
export const OptionLengthWrapper = styled.div<{ $gender: 'female' | 'male' }>` | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-end; | ||
align-items: center; | ||
gap: 5px; | ||
height: 100%; | ||
width: 20%; | ||
& > :first-child { | ||
position: relative; | ||
left: ${props => props.$gender === 'male' && '3px'}; | ||
right: ${props => props.$gender === 'female' && '3px'}; | ||
} | ||
`; | ||
|
||
export const OptionLength = styled.div<{ $amount: number; $gender: 'female' | 'male' }>` | ||
height: ${props => `${props.$amount}% `}; | ||
width: 100%; | ||
border-radius: 5px 5px 0 0; | ||
background-color: ${props => (props.$gender === 'female' ? '#853DE1' : '#5AEAA5')}; | ||
`; |
24 changes: 24 additions & 0 deletions
24
frontend/src/components/VoteStatistics/VoteStatistics.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import { mockVoteResult } from './mockData'; | ||
|
||
import VoteStatistics from '.'; | ||
|
||
const meta: Meta<typeof VoteStatistics> = { | ||
component: VoteStatistics, | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof VoteStatistics>; | ||
|
||
export const SizeSm: Story = { | ||
render: () => <VoteStatistics size="sm" voteResult={mockVoteResult} />, | ||
}; | ||
|
||
export const SizeMd: Story = { | ||
render: () => <VoteStatistics size="md" voteResult={mockVoteResult} />, | ||
}; | ||
|
||
export const SizeLg: Story = { | ||
render: () => <VoteStatistics size="lg" voteResult={mockVoteResult} />, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { MouseEvent, useState } from 'react'; | ||
|
||
import OneLineGraph from './OneLineGraph'; | ||
import * as S from './style'; | ||
import TwoLineGraph from './TwoLineGraph'; | ||
import { GraphProps } from './type'; | ||
|
||
interface RadioMode { | ||
all: string; | ||
gender: string; | ||
} | ||
|
||
const radioMode: RadioMode = { | ||
all: '전체보기', | ||
gender: '성별보기', | ||
}; | ||
|
||
type RadioCategory = keyof RadioMode; | ||
|
||
export default function VoteStatistics({ voteResult, size }: GraphProps) { | ||
const [nowRadioMode, setNowRadioMode] = useState<RadioCategory>('all'); | ||
|
||
const radioModeKey = Object.keys(radioMode) as RadioCategory[]; | ||
|
||
const changeMode = (e: MouseEvent<HTMLInputElement>) => { | ||
const target = e.target as HTMLInputElement; | ||
const targetCategory = target.value as RadioCategory; | ||
setNowRadioMode(targetCategory); | ||
}; | ||
|
||
return ( | ||
<S.Container> | ||
<S.CategoryWrapper> | ||
{radioModeKey.map(mode => { | ||
return ( | ||
<S.RadioLabel> | ||
<input | ||
type="radio" | ||
name="radio-category" | ||
value={mode} | ||
checked={mode === nowRadioMode} | ||
onClick={changeMode} | ||
/> | ||
{radioMode[mode]} | ||
</S.RadioLabel> | ||
); | ||
})} | ||
</S.CategoryWrapper> | ||
{nowRadioMode === 'all' && <OneLineGraph size={size} voteResult={voteResult} />} | ||
{nowRadioMode === 'gender' && <TwoLineGraph size={size} voteResult={voteResult} />} | ||
</S.Container> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export const mockVoteResult = { | ||
total: 100, | ||
female: 30, | ||
name: '총합', | ||
male: 70, | ||
age: { | ||
underTeenager: { total: 10, female: 10, male: 0, name: '10대 미만' }, | ||
teenager: { total: 20, female: 10, male: 10, name: '10대' }, | ||
twenties: { total: 10, female: 2, male: 8, name: '20대' }, | ||
thirties: { total: 20, female: 16, male: 4, name: '30대' }, | ||
forties: { total: 40, female: 30, male: 10, name: '40대' }, | ||
fifties: { total: 2, female: 1, male: 1, name: '50대' }, | ||
aboveFifties: { total: 3, female: 2, male: 1, name: '60대 이상' }, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { styled } from 'styled-components'; | ||
|
||
import { theme } from '@styles/theme'; | ||
|
||
export const Container = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
gap: 15px; | ||
font-size: 1.2rem; | ||
@media (min-width: ${theme.breakpoint.sm}) { | ||
font-size: 1.4rem; | ||
} | ||
`; | ||
|
||
export const CategoryWrapper = styled.fieldset` | ||
display: flex; | ||
gap: 10px; | ||
`; | ||
|
||
export const RadioLabel = styled.label` | ||
display: flex; | ||
gap: 5px; | ||
`; |
Oops, something went wrong.