Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 9385304

Browse files
authored
refactor(job-card): redesign && clean up (#1046)
* refactor(job-card): add images && footer adjust * refactor(IconText): convert to ts
1 parent bc2299f commit 9385304

File tree

9 files changed

+145
-69
lines changed

9 files changed

+145
-69
lines changed

src/components/Cards/JobCard.tsx

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import React from 'react'
66
import TimeAgo from 'timeago-react'
77

88
import { ICON } from '@/config'
9-
import { buildLog } from '@/utils'
9+
import { buildLog, uid } from '@/utils'
1010

11-
import { Space } from '@/components/Common'
11+
import { Space, SpaceGrow } from '@/components/Common'
1212
import IconText from '@/components/IconText'
1313
import Tooltip from '@/components/Tooltip'
1414

@@ -19,17 +19,21 @@ import {
1919
Header,
2020
TeamScale,
2121
Title,
22+
ShareIcon,
2223
Info,
2324
Sallery,
2425
Body,
2526
Footer,
26-
Publisher,
27-
Avatar,
2827
PublisherInfo,
2928
AuthorName,
3029
PublishExtra,
30+
PublishTime,
31+
TechstackWrapper,
32+
TechTitle,
3133
TechKeywords,
3234
Keyword,
35+
ImagesWrapper,
36+
PreviewImage,
3337
} from './styles/job_card'
3438

3539
/* eslint-disable-next-line */
@@ -46,11 +50,12 @@ type TProps = {
4650
title: string
4751
avatar: string
4852
}
53+
images?: string[]
4954
}
5055
}
5156

5257
const JobCard: React.FC<TProps> = ({
53-
item: { title, body, author, insertedAt, commentsCount },
58+
item: { title, body, author, insertedAt, commentsCount, images },
5459
}) => {
5560
const fakeCommunity = {
5661
id: '1',
@@ -67,39 +72,49 @@ const JobCard: React.FC<TProps> = ({
6772
<Wrapper>
6873
<Header>
6974
<Title>{title}</Title>
70-
<TeamScale>10~15 人</TeamScale>
75+
<ShareIcon src={`${ICON}/article/share.svg`} />
7176
</Header>
7277
<Info>
7378
<Sallery>成都</Sallery>
7479
<Sallery>前端</Sallery>
7580
<Sallery>15k-30k</Sallery>
81+
<SpaceGrow />
82+
<TeamScale>10~15 人</TeamScale>
7683
</Info>
7784
<Body>{body}</Body>
85+
{images && (
86+
<ImagesWrapper>
87+
{images.map((imageSrc) => (
88+
<PreviewImage key={uid.gen()} src={imageSrc} />
89+
))}
90+
</ImagesWrapper>
91+
)}
7892
<Footer>
79-
<Publisher>
80-
<Avatar src={author.avatar} />
81-
<PublisherInfo>
82-
<AuthorName>{author.title}</AuthorName>
83-
<PublishExtra>
84-
<IconText iconSrc={`${ICON}/edit/publish-pen.svg`}>
85-
<TimeAgo datetime={insertedAt} locale="zh_CN" />
86-
</IconText>
87-
<Space right={10} />
88-
<IconText iconSrc={`${ICON}/article/comment.svg`}>
89-
{commentsCount}
90-
</IconText>
91-
</PublishExtra>
92-
</PublisherInfo>
93-
</Publisher>
94-
<TechKeywords>
95-
<Tooltip
96-
content={<CommunityCard item={fakeCommunity} />}
97-
placement="top"
98-
>
99-
<Keyword>React</Keyword>
100-
</Tooltip>
101-
<Keyword>TS</Keyword>
102-
</TechKeywords>
93+
<TechstackWrapper>
94+
<TechTitle>技术栈</TechTitle>
95+
<TechKeywords>
96+
<Tooltip
97+
content={<CommunityCard item={fakeCommunity} />}
98+
placement="top"
99+
>
100+
<Keyword>React</Keyword>
101+
</Tooltip>
102+
<Keyword>TS</Keyword>
103+
</TechKeywords>
104+
</TechstackWrapper>
105+
106+
<PublisherInfo>
107+
<AuthorName>{author.title}</AuthorName>
108+
<PublishExtra>
109+
<PublishTime>
110+
<TimeAgo datetime={insertedAt} locale="zh_CN" />
111+
</PublishTime>
112+
<Space right={10} />
113+
<IconText iconSrc={`${ICON}/article/comment.svg`} size="medium">
114+
{commentsCount}
115+
</IconText>
116+
</PublishExtra>
117+
</PublisherInfo>
103118
</Footer>
104119
</Wrapper>
105120
)

src/components/Cards/styles/job_card.ts

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import { css, theme } from '@/utils'
77

88
export const Wrapper = styled.div`
99
background: #08303e;
10-
padding: 15px 20px;
10+
padding: 24px 22px;
1111
width: auto;
1212
height: auto;
1313
min-width: 400px;
1414
margin-bottom: 30px;
15-
border-radius: 4px;
15+
border-radius: 10px;
1616
`
1717
export const Header = styled.div`
1818
${css.flex('align-baseline', 'justify-between')};
@@ -21,6 +21,18 @@ export const Title = styled.div`
2121
color: ${theme('thread.articleTitle')};
2222
font-size: 16px;
2323
`
24+
export const ShareIcon = styled(Img)`
25+
fill: ${theme('thread.articleDigest')};
26+
${css.size(13)};
27+
margin-right: 4px;
28+
opacity: 0;
29+
30+
${Wrapper}:hover & {
31+
opacity: 1;
32+
}
33+
34+
transition: opacity 0.3s;
35+
`
2436
export const TeamScale = styled.div`
2537
color: ${theme('thread.articleDigest')};
2638
font-size: 12px;
@@ -41,26 +53,32 @@ export const Body = styled.div`
4153
`
4254
export const Footer = styled.div`
4355
width: 100%;
44-
${css.flex('align-center', 'justify-between')};
56+
${css.flex('align-end', 'justify-between')};
4557
margin-top: 20px;
4658
`
47-
export const Publisher = styled.div`
48-
${css.flex('align-center')};
49-
`
50-
export const Avatar = styled(Img)`
51-
${css.circle(22)};
52-
`
5359
export const PublisherInfo = styled.div`
54-
${css.flexColumn()};
55-
margin-left: 14px;
60+
${css.flexColumn('align-end')};
5661
`
5762
export const AuthorName = styled.div`
5863
font-size: 14px;
59-
color: ${theme('thread.articleTitle')};
64+
color: ${theme('thread.articleDigest')};
65+
margin-bottom: 3px;
6066
`
6167
export const PublishExtra = styled.div`
6268
${css.flex('align-center')};
6369
`
70+
export const PublishTime = styled.div`
71+
font-size: 11px;
72+
color: ${theme('thread.articleDigest')};
73+
`
74+
export const TechstackWrapper = styled.div`
75+
${css.flexColumn()};
76+
`
77+
export const TechTitle = styled.div`
78+
font-size: 11px;
79+
color: ${theme('thread.articleDigest')};
80+
margin-bottom: 2px;
81+
`
6482
export const TechKeywords = styled.div`
6583
${css.flex('align-center')};
6684
`
@@ -74,3 +92,16 @@ export const Keyword = styled.a`
7492
cursor: pointer;
7593
}
7694
`
95+
export const ImagesWrapper = styled.div`
96+
${css.flex('align-center')};
97+
width: 80%;
98+
margin-top: 24px;
99+
margin-bottom: 6px;
100+
`
101+
export const PreviewImage = styled(Img)`
102+
width: auto;
103+
height: 60px;
104+
object-fit: cover;
105+
border-radius: 8px;
106+
margin-right: 12px;
107+
`

src/components/IconText/index.js renamed to src/components/IconText/index.tsx

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
*/
66

77
import React from 'react'
8-
import T from 'prop-types'
9-
import { values } from 'ramda'
108

9+
import type { TSIZE } from '@/spec'
1110
import { buildLog, nilOrEmpty } from '@/utils'
1211
import { SIZE } from '@/constant'
1312

@@ -16,7 +15,21 @@ import { Wrapper, Icon, Text } from './styles'
1615
/* eslint-disable-next-line */
1716
const log = buildLog('c:IconText:index')
1817

19-
const IconText = ({ iconSrc, round, children, size, margin }) => (
18+
type TProps = {
19+
iconSrc: string
20+
round?: boolean
21+
children: React.ReactNode
22+
size?: TSIZE
23+
margin?: string
24+
}
25+
26+
const IconText: React.FC<TProps> = ({
27+
iconSrc,
28+
round = false,
29+
children,
30+
size = SIZE.SMALL,
31+
margin,
32+
}) => (
2033
<Wrapper testid="iconText">
2134
{!nilOrEmpty(iconSrc) && (
2235
<Icon src={iconSrc} size={size} round={round} margin={margin} />
@@ -25,19 +38,4 @@ const IconText = ({ iconSrc, round, children, size, margin }) => (
2538
</Wrapper>
2639
)
2740

28-
IconText.propTypes = {
29-
iconSrc: T.string,
30-
round: T.bool,
31-
children: T.oneOfType([T.node, T.string]).isRequired,
32-
size: T.oneOf(values(SIZE)),
33-
margin: T.oneOfType([T.string, T.instanceOf(null)]),
34-
}
35-
36-
IconText.defaultProps = {
37-
iconSrc: '',
38-
round: false,
39-
size: SIZE.SMALL,
40-
margin: null,
41-
}
42-
4341
export default React.memo(IconText)

src/components/IconText/styles/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import styled from 'styled-components'
22

3-
import type { TTestable } from '@/spec'
3+
import type { TTestable, TSIZE } from '@/spec'
44
import Img from '@/Img'
55
import { css, theme } from '@/utils'
66

77
import { getIconSize, getTextSize, getMargin } from './metric'
88

99
type TIcon = {
10-
size: string
10+
size: TSIZE
1111
margin: string
12-
round: string
12+
round: boolean
1313
}
1414

1515
export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({
@@ -25,7 +25,7 @@ export const Icon = styled(Img)<TIcon>`
2525
display: block;
2626
border-radius: ${({ round }) => (round ? '100%' : '0')};
2727
`
28-
export const Text = styled.div<{ size: string }>`
28+
export const Text = styled.div<{ size: TSIZE }>`
2929
${css.flex('align-center')};
3030
color: ${theme('thread.articleDigest')};
3131
font-size: ${({ size }) => getTextSize(size)};

src/components/IconText/styles/metric.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import type { TSIZE } from '@/spec'
12
import { SIZE } from '@/constant'
23

3-
export const getIconSize = (size: string): string => {
4+
export const getIconSize = (size: TSIZE): string => {
45
switch (size) {
56
case SIZE.LARGE: {
7+
return '14px'
8+
}
9+
case SIZE.MEDIUM: {
610
return '13px'
711
}
812
case SIZE.TINY: {
@@ -17,7 +21,7 @@ export const getIconSize = (size: string): string => {
1721
}
1822
}
1923

20-
export const getTextSize = (size: string): string => {
24+
export const getTextSize = (size: TSIZE): string => {
2125
switch (size) {
2226
case SIZE.LARGE: {
2327
return '15px'
@@ -31,11 +35,14 @@ export const getTextSize = (size: string): string => {
3135
}
3236
}
3337

34-
export const getMargin = (size: string): string => {
38+
export const getMargin = (size: TSIZE): string => {
3539
switch (size) {
3640
case SIZE.LARGE: {
3741
return '8px'
3842
}
43+
case SIZE.MEDIUM: {
44+
return '5px'
45+
}
3946
case SIZE.TINY: {
4047
return '2px'
4148
}

src/containers/thread/JobsThread/fakeFiltersItems.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const filtersItems = [
6363
},
6464
{
6565
id: '102',
66-
title: '薪资待遇',
66+
title: '月薪',
6767
icon: `${ICON_CMD}/navi/money-yuan.svg`,
6868

6969
options: [
@@ -96,7 +96,7 @@ const filtersItems = [
9696
{
9797
// 非 IT,设计类的网站
9898
id: '103',
99-
title: '规模',
99+
title: '团队规模',
100100
icon: `${ICON_CMD}/navi/chair.svg`,
101101
options: [
102102
{

src/containers/thread/JobsThread/fakeJobItems.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { mockImages } from '@/utils'
2+
13
const fakeItems = [
24
{
35
id: '1',
@@ -10,6 +12,7 @@ const fakeItems = [
1012
},
1113
body:
1214
'美团校招内推启动啦!!!校园招聘已启动~2021届应届生&&2022届实习, 美团校招内推启动啦!!!内推的优势: 免简历筛选,直通笔试,更大概率被发起面试, 极大增加通过概率 !… ',
15+
images: mockImages(2),
1316
},
1417
{
1518
id: '2',
@@ -34,6 +37,7 @@ const fakeItems = [
3437
},
3538
body:
3639
'岗位多样,开发,美术,市场,运营,产品,设计,财务,法律等。不卡学历!各类岗位面试难度一般,对学历无歧视,内推保证直通笔试面试,拿个保底offer吧各位',
40+
images: mockImages(3),
3741
},
3842
{
3943
id: '4',
@@ -45,6 +49,7 @@ const fakeItems = [
4549
avatar: 'https://avatars.githubusercontent.com/u/809410?s=64&v=4',
4650
},
4751
body: '美团校招内推启动啦!!!校园招聘已启动~2021届应届生&&2022届实习',
52+
images: mockImages(1),
4853
},
4954
{
5055
id: '5',

utils/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,5 @@ export { Trans } from './i18n'
143143
export { default as GA } from './analytics'
144144

145145
export { isMobile } from './device'
146+
147+
export { mockImage, mockImages } from './mock'

0 commit comments

Comments
 (0)