-
Notifications
You must be signed in to change notification settings - Fork 1
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
design: 톡앤픽 플레이스 Page UI 구현 #155
Changes from 6 commits
ff009fe
01380a9
00c4a0d
ed6a8fc
5770c31
f91ec60
328f72b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { css } from '@emotion/react'; | ||
import typo from '@/styles/typo'; | ||
import color from '@/styles/color'; | ||
import type { TalkPickListItemProps } from './TalkPickItem'; | ||
|
||
export const commonNumberStyle = css(typo.Number.Medium, { | ||
color: color.GY[1], | ||
}); | ||
|
||
export const bestNumberStyle = css(typo.Number.Medium, { | ||
color: color.MAIN, | ||
}); | ||
|
||
export const commonStyle = css(typo.Comment.SemiBold, { | ||
color: color.GY[1], | ||
}); | ||
|
||
export const headerStyle = css(typo.Main.Medium, { | ||
color: color.BK, | ||
}); | ||
|
||
export const borderBottomStyling = css({ | ||
borderBottom: '1px solid #F4F4F4', | ||
}); | ||
|
||
export const centerStyling = css({ | ||
display: 'flex', | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
}); | ||
|
||
export const talkPickListItemStyling = css({ | ||
display: 'flex', | ||
alignItems: 'center', | ||
width: '1174px', | ||
height: '60px', | ||
}); | ||
|
||
export const talkPickListId = css([ | ||
centerStyling, | ||
{ | ||
width: '112px', | ||
color: color.GY[1], | ||
}, | ||
]); | ||
|
||
export const getTalkPickListIdStyling = ( | ||
type: Required<TalkPickListItemProps>['type'], | ||
) => { | ||
return type === 'best' ? bestNumberStyle : commonNumberStyle; | ||
}; | ||
|
||
export const talkPickListTitle = css({ | ||
width: '570px', | ||
padding: '0 10px', | ||
whiteSpace: 'nowrap', | ||
overflow: 'hidden', | ||
textOverflow: 'ellipsis', | ||
color: color.BK, | ||
}); | ||
|
||
export const talkPickTitleText = css({ | ||
cursor: 'pointer', | ||
}); | ||
|
||
export const getTalkPickListTitleStyling = ( | ||
type: Required<TalkPickListItemProps>['type'], | ||
) => { | ||
const style = { | ||
header: css(typo.Main.Medium, centerStyling), | ||
default: css(typo.Main.Medium), | ||
best: css(typo.Main.SemiBold, { | ||
fontWeight: 'bold', | ||
}), | ||
}; | ||
|
||
return style[type]; | ||
}; | ||
|
||
export const getTalkPickListWriterStyling = ( | ||
type: Required<TalkPickListItemProps>['type'], | ||
) => { | ||
return type === 'header' ? headerStyle : commonStyle; | ||
}; | ||
|
||
export const talkPickListWideDetail = css([ | ||
centerStyling, | ||
{ | ||
width: '148px', | ||
}, | ||
]); | ||
|
||
export const talkPickListDetail = css([ | ||
centerStyling, | ||
{ | ||
width: '85px', | ||
}, | ||
]); | ||
|
||
export const getTalkPickListDetailStyling = ( | ||
type: Required<TalkPickListItemProps>['type'], | ||
) => { | ||
return type === 'header' ? headerStyle : commonNumberStyle; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import React from 'react'; | ||
import { TalkPickListItem } from '@/types/talk-pick'; | ||
import { formatDate, formatNumber } from '@/utils/formatData'; | ||
import * as S from './TalkPickItem.style'; | ||
|
||
export interface TalkPickListItemProps { | ||
type?: 'header' | 'default' | 'best'; | ||
rank?: number; | ||
talkPickItem?: TalkPickListItem; | ||
} | ||
|
||
const headerTalkPick: TalkPickListItem = { | ||
id: 0, | ||
title: '제목', | ||
writer: '작성자', | ||
createdAt: '작성일시', | ||
views: '조회수', | ||
bookmarks: '저장수', | ||
}; | ||
|
||
const TalkPickItem = ({ | ||
type = 'default', | ||
rank, | ||
talkPickItem = headerTalkPick, | ||
}: TalkPickListItemProps) => { | ||
const getTalkPickId = (): number | undefined => { | ||
switch (type) { | ||
case 'default': | ||
return talkPickItem.id; | ||
case 'best': | ||
return rank; | ||
case 'header': | ||
default: | ||
return undefined; | ||
} | ||
}; | ||
|
||
const getFormatNumber = (item: number | string): string => { | ||
return typeof item === 'number' ? formatNumber(item) : item; | ||
}; | ||
|
||
return ( | ||
<div | ||
css={[ | ||
S.talkPickListItemStyling, | ||
type !== 'header' && S.borderBottomStyling, | ||
]} | ||
> | ||
<div css={[S.talkPickListId, S.getTalkPickListIdStyling(type)]}> | ||
{getTalkPickId()} | ||
</div> | ||
<div css={[S.talkPickListTitle, S.getTalkPickListTitleStyling(type)]}> | ||
<span css={type !== 'header' && S.talkPickTitleText}> | ||
{talkPickItem.title} | ||
</span> | ||
</div> | ||
<div | ||
css={[S.talkPickListWideDetail, S.getTalkPickListWriterStyling(type)]} | ||
> | ||
{talkPickItem.writer} | ||
</div> | ||
<div | ||
css={[S.talkPickListWideDetail, S.getTalkPickListDetailStyling(type)]} | ||
> | ||
{formatDate(talkPickItem.createdAt)} | ||
</div> | ||
<div css={[S.talkPickListDetail, S.getTalkPickListDetailStyling(type)]}> | ||
{getFormatNumber(talkPickItem.views)} | ||
</div> | ||
<div css={[S.talkPickListDetail, S.getTalkPickListDetailStyling(type)]}> | ||
{getFormatNumber(talkPickItem.bookmarks)} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default TalkPickItem; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { css } from '@emotion/react'; | ||
import typo from '@/styles/typo'; | ||
import color from '@/styles/color'; | ||
|
||
export const bestTalkPickContainer = css({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
paddingTop: '30px', | ||
paddingBottom: '40px', | ||
borderRadius: '20px', | ||
border: `1px solid ${color.GY[2]}`, | ||
boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)', | ||
}); | ||
|
||
export const bestTalkPickText = css(typo.Title, { | ||
padding: '0 40px', | ||
color: color.MAIN, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import React from 'react'; | ||
import { TalkPickListItem } from '@/types/talk-pick'; | ||
import TalkPickItem from '@/components/atoms/TalkPickItem/TalkPickItem'; | ||
import * as S from './BestTalkPick.style'; | ||
|
||
export interface BestTalkPickProps { | ||
bestTalkPick: TalkPickListItem[]; | ||
} | ||
|
||
const BestTalkPick = ({ bestTalkPick }: BestTalkPickProps) => ( | ||
<div css={S.bestTalkPickContainer}> | ||
<div css={S.bestTalkPickText}>BEST 3</div> | ||
<TalkPickItem type="header" /> | ||
{bestTalkPick.map((talkPick, idx) => ( | ||
<TalkPickItem | ||
key={talkPick.id} | ||
type="best" | ||
rank={idx + 1} | ||
talkPickItem={talkPick} | ||
/> | ||
))} | ||
</div> | ||
); | ||
|
||
export default BestTalkPick; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { css } from '@emotion/react'; | ||
import color from '@/styles/color'; | ||
|
||
export const talkPickListContainer = css({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
padding: '12px 0', | ||
borderTop: `1px solid ${color.GY[2]}`, | ||
}); | ||
|
||
export const talkPickListWrapper = css({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import React from 'react'; | ||
import { TalkPickListItem } from '@/types/talk-pick'; | ||
import TalkPickItem from '@/components/atoms/TalkPickItem/TalkPickItem'; | ||
import * as S from './TalkPickList.style'; | ||
|
||
export interface TalkPickListProps { | ||
talkPickList: TalkPickListItem[]; | ||
} | ||
|
||
const TalkPickList = ({ talkPickList }: TalkPickListProps) => ( | ||
<div css={S.talkPickListContainer}> | ||
<div css={S.talkPickListWrapper}> | ||
<TalkPickItem type="header" /> | ||
{talkPickList.map((talkPick) => ( | ||
<TalkPickItem | ||
key={talkPick.id} | ||
type="default" | ||
talkPickItem={talkPick} | ||
/> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
|
||
export default TalkPickList; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ export const footerContainer = css` | |
display: flex; | ||
flex-direction: column; | ||
background-color: ${color.BLUE_LIGHT}; | ||
width: 1920px; | ||
width: 100%; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. header와 footer의 경우, 전체 layout을 , 나머지 요소들은 양 옆 간격을 가지고 표시되기 때문에 1920px 로 지정해놨었는데, 100%로 처리하고 안에 요소들에 margin 을 설정하는 것도 좋은 방법이네요! |
||
height: 427px; | ||
padding-left: 200px; | ||
`; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,8 @@ export const containerStyle = css({ | |
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'space-between', | ||
backgroundColor: '#ffffff', | ||
backgroundColor: color.WT, | ||
boxShadow: '0px 4px 11px rgba(0, 0, 0, 0.1)', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분 저도 이번에 확인하고 수정했는데..! 감사합니다🙂 |
||
}); | ||
|
||
export const logoStyle = css({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { css } from '@emotion/react'; | ||
|
||
export const talkPickListContainer = css({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
}); | ||
|
||
export const talkPickBtnWrapper = css({ | ||
display: 'flex', | ||
justifyContent: 'space-between', | ||
width: '100%', | ||
alignItems: 'flex-end', | ||
padding: '0 5px', | ||
}); | ||
|
||
export const talkPickListWrapper = css({ | ||
paddingTop: '10px', | ||
paddingBottom: '60px', | ||
}); | ||
|
||
export const talkPickWriteBtnWrapper = css({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'flex-end', | ||
gap: '5px', | ||
}); | ||
|
||
export const talkPickWriteBtn = css({ | ||
width: '108px', | ||
marginRight: '5px', | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
talkpickId를 props 로 받게 된다면, case에 따른 로직을 utils에 정의하는 것도 좋아보여요 😄