1
1
import React , { ReactNode } from "react"
2
- import styled from "@emotion/styled"
3
2
import { GatsbyImage , IGatsbyImageData } from "gatsby-plugin-image"
4
3
import { useQuery , gql } from "@apollo/client"
4
+ import {
5
+ Box ,
6
+ Center ,
7
+ Flex ,
8
+ Heading ,
9
+ HStack ,
10
+ Img ,
11
+ Text ,
12
+ TextProps ,
13
+ } from "@chakra-ui/react"
5
14
6
15
import GitStars from "./GitStars"
7
16
import ButtonLink from "./ButtonLink"
8
17
9
- const ImageWrapper = styled . div < {
10
- background : string
11
- } > `
12
- display: flex;
13
- flex-direction: row;
14
- justify-content: center;
15
- align-items: center;
16
- background: ${ ( props ) => props . background } ;
17
- box-shadow: inset 0px -1px 0px rgba(0, 0, 0, 0.1);
18
- min-height: 200px;
19
- `
20
-
21
- const Image = styled ( GatsbyImage ) `
22
- width: 100%;
23
- align-self: center;
24
- max-width: 372px;
25
- max-height: 257px;
26
- @media (max-width: ${ ( props ) => props . theme . breakpoints . s } ) {
27
- max-width: 311px;
28
- }
29
- `
30
-
31
- const Card = styled . div `
32
- color: ${ ( props ) => props . theme . colors . text } ;
33
- box-shadow: 0px 14px 66px rgba(0, 0, 0, 0.07);
34
- display: flex;
35
- flex-direction: column;
36
- justify-content: space-between;
37
- background: ${ ( props ) => props . theme . colors . searchBackground } ;
38
- border-radius: 4px;
39
- border: 1px solid ${ ( props ) => props . theme . colors . lightBorder } ;
40
- text-decoration: none;
41
- &:hover {
42
- transition: transform 0.1s;
43
- transform: scale(1.02);
44
- }
45
- `
46
-
47
- const Content = styled . div `
48
- padding: 1.5rem;
49
- text-align: left;
50
- height: 100%;
51
- display: flex;
52
- flex-direction: column;
53
- `
54
-
55
- const Title = styled . h3 < {
56
- gitHidden : boolean
57
- } > `
58
- margin-top: ${ ( props ) => ( props . gitHidden ? "2rem" : "3rem" ) } ;
59
- margin-bottom: 0.75rem;
60
- `
61
-
62
- const Description = styled . p `
63
- opacity: 0.8;
64
- font-size: ${ ( props ) => props . theme . fontSizes . s } ;
65
- margin-bottom: 0.5rem;
66
- line-height: 140%;
67
- `
68
-
69
- const SubjectContainer = styled . div `
70
- margin-top: 1.25rem;
71
- padding: 0 1.5rem;
72
- `
73
-
74
- const SubjectPill = styled . div < {
75
- subject : string
76
- } > `
77
- text-align: center;
78
- padding: 0 0.5rem;
79
- margin: 0 0.75rem 0.5rem 0;
80
- color: ${ ( props ) => props . theme . colors . black300 } ;
81
- float: left;
82
- background: ${ ( { theme, subject } ) => {
83
- switch ( subject ) {
84
- case "Solidity" :
85
- return theme . colors . tagYellow
86
- case "Vyper" :
87
- return theme . colors . tagBlue
88
- case "web3" :
89
- return theme . colors . tagTurquoise
90
- case "JavaScript" :
91
- return theme . colors . tagRed
92
- case "TypeScript" :
93
- return theme . colors . tagBlue
94
- case "Go" :
95
- return theme . colors . tagTurquoise
96
- case "Python" :
97
- return theme . colors . tagMint
98
- case "Rust" :
99
- return theme . colors . tagOrange
100
- case "C#" :
101
- return theme . colors . tagBlue
102
- case "Java" :
103
- return theme . colors . tagPink
104
- default :
105
- return theme . colors . tagGray
106
- }
107
- } } ;
108
- font-size: ${ ( props ) => props . theme . fontSizes . xs } ;
109
- border: 1px solid ${ ( props ) => props . theme . colors . lightBorder } ;
110
- border-radius: 4px;
111
- `
112
-
113
- const StyledButtonLink = styled ( ButtonLink ) `
114
- margin: 1rem;
115
- `
116
-
117
- const Children = styled . div `
118
- margin-top: 1rem;
119
- `
120
-
121
18
const REPO_DATA = gql `
122
19
query RepoData(
123
20
$repoOwner: String!
@@ -139,6 +36,52 @@ const REPO_DATA = gql`
139
36
}
140
37
`
141
38
39
+ const SubjectPill : React . FC < { subject : string ; children : ReactNode } > = ( {
40
+ subject,
41
+ children,
42
+ } ) => {
43
+ const bgColor = ( ) => {
44
+ switch ( subject ) {
45
+ case "Solidity" :
46
+ return "tagYellow"
47
+ case "Vyper" :
48
+ return "tagBlue"
49
+ case "web3" :
50
+ return "tagTurquoise"
51
+ case "JavaScript" :
52
+ return "tagRed"
53
+ case "TypeScript" :
54
+ return "tagBlue"
55
+ case "Go" :
56
+ return "tagTurquoise"
57
+ case "Python" :
58
+ return "tagMint"
59
+ case "Rust" :
60
+ return "tagOrange"
61
+ case "C#" :
62
+ return "tagBlue"
63
+ case "Java" :
64
+ return "tagPink"
65
+ default :
66
+ return "tagGray"
67
+ }
68
+ }
69
+ return (
70
+ < Box
71
+ background = { bgColor ( ) }
72
+ border = "1px"
73
+ borderColor = "lightBorder"
74
+ borderRadius = "base"
75
+ color = "black300"
76
+ fontSize = "xs"
77
+ textAlign = "center"
78
+ px = { 2 }
79
+ >
80
+ { children }
81
+ </ Box >
82
+ )
83
+ }
84
+
142
85
export interface IProps {
143
86
children ?: React . ReactNode
144
87
url : string
@@ -156,7 +99,7 @@ export interface IProps {
156
99
157
100
const ProductCard : React . FC < IProps > = ( {
158
101
url,
159
- background,
102
+ background : bgProp ,
160
103
image,
161
104
name,
162
105
description,
@@ -186,27 +129,67 @@ const ProductCard: React.FC<IProps> = ({
186
129
187
130
const isImgSrc = typeof image === "string"
188
131
132
+ const DESCRIPTION_STYLES : TextProps = {
133
+ opacity : 0.8 ,
134
+ fontSize : "sm" ,
135
+ mb : 2 ,
136
+ lineHeight : "140%" ,
137
+ }
138
+
189
139
return (
190
- < Card >
191
- < ImageWrapper background = { background } >
140
+ < Flex
141
+ flexDirection = "column"
142
+ justifyContent = "space-between"
143
+ color = "text"
144
+ background = "searchBackground"
145
+ boxShadow = "0px 14px 66px rgba(0, 0, 0, 0.07)"
146
+ borderRadius = "base"
147
+ border = "1px"
148
+ borderColor = "lightBorder"
149
+ textDecoration = "none"
150
+ _hover = { {
151
+ transition : "transform 0.1s" ,
152
+ transform : "scale(1.02)" ,
153
+ } }
154
+ >
155
+ < Center
156
+ background = { bgProp }
157
+ boxShadow = "inset 0px -1px 0px rgba(0, 0, 0, 0.1)"
158
+ minH = "200px"
159
+ >
192
160
{ isImgSrc ? (
193
161
< img src = { image } alt = { alt } />
194
162
) : (
195
- < Image image = { image } alt = { alt } objectFit = "contain" />
163
+ < Img
164
+ as = { GatsbyImage }
165
+ image = { image }
166
+ alt = { alt }
167
+ objectFit = "contain"
168
+ width = "100%"
169
+ alignSelf = "center"
170
+ maxW = { { base : "311px" , sm : "372px" } }
171
+ maxH = "257px"
172
+ />
196
173
) }
197
- </ ImageWrapper >
198
- < Content className = "hover" >
199
- < div >
200
- { hasRepoData && (
201
- < GitStars gitHubRepo = { data . repository } hideStars = { hideStars } />
202
- ) }
203
- < Title gitHidden = { ! hasRepoData } > { name } </ Title >
204
- < Description > { description } </ Description >
205
- { note . length > 0 && < Description > Note: { note } </ Description > }
206
- </ div >
207
- { children && < Children > { children } </ Children > }
208
- </ Content >
209
- < SubjectContainer >
174
+ </ Center >
175
+ < Flex flexDirection = "column" p = { 6 } textAlign = "left" height = "100%" >
176
+ { hasRepoData && (
177
+ < GitStars gitHubRepo = { data . repository } hideStars = { hideStars } />
178
+ ) }
179
+ < Heading
180
+ as = "h3"
181
+ fontSize = "2xl"
182
+ fontWeight = { 600 }
183
+ mt = { ! hasRepoData ? 8 : 12 }
184
+ mb = { 3 }
185
+ >
186
+ { name }
187
+ </ Heading >
188
+ { description && < Text { ...DESCRIPTION_STYLES } > { description } </ Text > }
189
+ { note . length > 0 && < Text { ...DESCRIPTION_STYLES } > Note: { note } </ Text > }
190
+ { children && < Box mt = { 4 } > { children } </ Box > }
191
+ </ Flex >
192
+ < HStack mt = { 5 } mb = { 2 } px = { 6 } spacing = { 3 } >
210
193
{ subjects &&
211
194
subjects . map ( ( subject , idx ) => (
212
195
< SubjectPill key = { idx } subject = { subject } >
@@ -221,11 +204,11 @@ const ProductCard: React.FC<IProps> = ({
221
204
</ SubjectPill >
222
205
)
223
206
) }
224
- </ SubjectContainer >
225
- < StyledButtonLink h = { 20 } to = { url } >
207
+ </ HStack >
208
+ < ButtonLink to = { url } m = { 4 } height = { 20 } >
226
209
Open { name }
227
- </ StyledButtonLink >
228
- </ Card >
210
+ </ ButtonLink >
211
+ </ Flex >
229
212
)
230
213
}
231
214
0 commit comments