1
1
import React , {
2
2
ComponentType ,
3
+ ReactNode ,
3
4
SVGProps ,
4
- useContext ,
5
5
useEffect ,
6
6
useState ,
7
7
} from "react"
8
- import styled from "@emotion/styled"
9
- import { useTheme } from "@emotion/react"
10
8
import { shuffle } from "lodash"
9
+ import {
10
+ Box ,
11
+ BoxProps ,
12
+ Center ,
13
+ Flex ,
14
+ Heading ,
15
+ HStack ,
16
+ Icon ,
17
+ List ,
18
+ ListIcon ,
19
+ ListItem ,
20
+ SimpleGrid ,
21
+ useColorModeValue ,
22
+ } from "@chakra-ui/react"
11
23
// Data imports
12
24
import stakingProducts from "../../data/staking-products.json"
13
25
// Component imports
@@ -38,135 +50,17 @@ import Wagyu from "../../assets/staking/wagyu-glyph.svg"
38
50
import { EventOptions } from "../../utils/matomo"
39
51
// When adding a product svg, be sure to add to mapping below as well.
40
52
41
- const CardGrid = styled . div `
42
- display: grid;
43
- grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
44
- gap: 2rem;
45
- margin: 3rem 0;
46
- `
47
-
48
- const Card = styled . div `
49
- display: flex;
50
- flex-direction: column;
51
- background: ${ ( { theme } ) => theme . colors . offBackground } ;
52
- border-radius: 0.25rem;
53
- &:hover {
54
- transition: 0.1s;
55
- transform: scale(1.01);
56
- }
57
- `
58
-
59
- const PaddedDiv = styled . div `
60
- padding: 1.5rem 2rem;
61
- `
62
-
63
- const Spacer = styled . div `
64
- flex: 1;
65
- `
66
-
67
- const Banner = styled ( PaddedDiv ) `
68
- display: flex;
69
- align-items: center;
70
- gap: 1.5rem;
71
- background: ${ ( { color } ) => color }
72
- linear-gradient(0deg, rgba(0, 0, 0, 30%), rgba(0, 0, 0, 0));
73
- border-radius: 0.25rem;
74
- max-height: 6rem;
75
- h2 {
76
- margin: 0;
77
- color: white;
78
- font-size: 1.5rem;
79
- }
80
- svg {
81
- height: 2rem;
82
- }
83
- `
84
-
85
- const MinEthBar = styled . div `
86
- display: flex;
87
- justify-content: center;
88
- align-items: center;
89
- font-weight: 700;
90
- font-size: 1rem;
91
- color: ${ ( { theme } ) => theme . colors . textTableOfContents } ;
92
- text-transform: uppercase;
93
- padding-top: 1.5rem;
94
- `
95
-
96
- const Pills = styled ( PaddedDiv ) `
97
- display: flex;
98
- flex-wrap: wrap;
99
- gap: 0.25rem;
100
- /* padding-top: 1rem; */
101
- `
102
-
103
- const Pill = styled . div < { type : string } > `
104
- text-align: center;
105
- padding: 0.25rem 0.75rem;
106
- color: ${ ( { theme, type } ) =>
107
- type ? "rgba(0, 0, 0, 0.6)" : theme . colors . text200 } ;
108
- background: ${ ( { theme, type } ) => {
109
- if ( ! type ) return "transparent"
110
- switch ( type . toLowerCase ( ) ) {
111
- case "ui" :
112
- return theme . colors . stakingPillUI
113
- case "platform" :
114
- return theme . colors . stakingPillPlatform
115
- default :
116
- return theme . colors . tagGray
117
- }
118
- } } ;
119
- font-size: ${ ( { theme } ) => theme . fontSizes . xs } ;
120
- border: 1px solid ${ ( { theme } ) => theme . colors . lightBorder } ;
121
- border-radius: 0.25rem;
122
- `
123
-
124
- const Content = styled ( PaddedDiv ) `
125
- padding-top: 0;
126
- padding-bottom: 0;
127
-
128
- ul {
129
- list-style: none;
130
- margin-left: 0;
131
- padding-left: 0;
132
- }
133
- `
134
-
135
- const Item = styled . li `
136
- display: flex;
137
- align-items: center;
138
- text-indent: 1em;
139
- text-transform: uppercase;
140
- font-weight: 400;
141
- font-size: 0.75rem;
142
- line-height: 0.875rem;
143
- letter-spacing: 0.04em;
144
-
145
- p {
146
- margin: 1rem auto 1rem 0;
147
- }
148
- `
149
-
150
- const Cta = styled ( PaddedDiv ) `
151
- a {
152
- width: 100%;
153
- }
154
- `
53
+ const PADDED_DIV_STYLE : BoxProps = {
54
+ px : 8 ,
55
+ py : 6 ,
56
+ }
155
57
156
- const Status : React . FC < { status : FlagType } > = ( { status } ) => {
157
- if ( ! status ) return null
158
- const styles = { width : "24" , height : "auto" }
159
- switch ( status ) {
160
- case "green-check" :
161
- return < GreenCheck style = { styles } />
162
- case "caution" :
163
- return < Caution style = { styles } />
164
- case "warning" :
165
- case "false" :
166
- return < Warning style = { styles } />
167
- default :
168
- return < Unknown style = { styles } />
169
- }
58
+ enum FlagType {
59
+ VALID = "green-check" ,
60
+ CAUTION = "caution" ,
61
+ WARNING = "warning" ,
62
+ FALSE = "false" ,
63
+ UNKNOWN = "unknown" ,
170
64
}
171
65
172
66
const getSvgFromPath = (
@@ -192,12 +86,54 @@ const getSvgFromPath = (
192
86
}
193
87
return mapping [ svgPath ]
194
88
}
195
- enum FlagType {
196
- VALID = "green-check" ,
197
- CAUTION = "caution" ,
198
- WARNING = "warning" ,
199
- FALSE = "false" ,
200
- UNKNOWN = "unknown" ,
89
+
90
+ const Status : React . FC < { status : FlagType } > = ( { status } ) => {
91
+ if ( ! status ) return null
92
+
93
+ const styles = { fontSize : "2xl" , m : 0 }
94
+ switch ( status ) {
95
+ case "green-check" :
96
+ return < ListIcon as = { GreenCheck } { ...styles } />
97
+ case "caution" :
98
+ return < ListIcon as = { Caution } { ...styles } />
99
+ case "warning" :
100
+ case "false" :
101
+ return < ListIcon as = { Warning } { ...styles } />
102
+ default :
103
+ return < ListIcon as = { Unknown } { ...styles } />
104
+ }
105
+ }
106
+
107
+ const StakingPill : React . FC < { type : string ; children : ReactNode } > = ( {
108
+ type,
109
+ children,
110
+ } ) => {
111
+ const backgroundColor = ( ) => {
112
+ if ( ! type ) return "transparent"
113
+ switch ( type . toLowerCase ( ) ) {
114
+ case "ui" :
115
+ return "stakingPillUI"
116
+ case "platform" :
117
+ return "stakingPillPlatform"
118
+ default :
119
+ return "tagGray"
120
+ }
121
+ }
122
+ return (
123
+ < Box
124
+ background = { backgroundColor ( ) }
125
+ border = "1px"
126
+ borderColor = "lightBorder"
127
+ borderRadius = "base"
128
+ color = { type ? "rgba(0,0,0,0.6)" : "text200" }
129
+ fontSize = "xs"
130
+ px = { 3 }
131
+ py = { 1 }
132
+ textAlign = "center"
133
+ >
134
+ { children }
135
+ </ Box >
136
+ )
201
137
}
202
138
203
139
type Product = {
@@ -303,48 +239,89 @@ const StakingProductCard: React.FC<ICardProps> = ({
303
239
] . filter ( ( { status } ) => ! ! status )
304
240
305
241
return (
306
- < Card >
307
- < Banner color = { color } >
308
- { ! ! Svg && < Svg style = { { width : "32" , height : "auto" } } /> }
309
- < h2 > { name } </ h2 >
310
- </ Banner >
242
+ < Flex
243
+ direction = "column"
244
+ background = "offBackground"
245
+ borderRadius = "base"
246
+ _hover = { {
247
+ transition : "0.1s" ,
248
+ transform : "scale(1.01)" ,
249
+ } }
250
+ >
251
+ < HStack
252
+ { ...PADDED_DIV_STYLE }
253
+ spacing = { 6 }
254
+ background = { color }
255
+ bgGradient = "linear(0deg, rgba(0, 0, 0, 30%), rgba(0, 0, 0, 0))"
256
+ borderRadius = "base"
257
+ maxH = { 24 }
258
+ >
259
+ { ! ! Svg && < Icon as = { Svg } fontSize = "2rem" /> }
260
+ < Heading fontSize = "2xl" color = "white" >
261
+ { name }
262
+ </ Heading >
263
+ </ HStack >
311
264
{ typeof minEth !== "undefined" && (
312
- < MinEthBar >
313
- { minEth > 0 ? `From ${ minEth } ETH` : "Any amount" }
314
- </ MinEthBar >
265
+ < Center
266
+ fontWeight = { 700 }
267
+ fontSize = "base"
268
+ color = "textTableOfContents"
269
+ textTransform = "uppercase"
270
+ pt = { 6 }
271
+ >
272
+ { minEth > 0 ? `From ${ minEth } ETH` : "Any amount" }
273
+ </ Center >
315
274
) }
316
- < Pills >
275
+ < Flex
276
+ { ...PADDED_DIV_STYLE }
277
+ flexWrap = "wrap"
278
+ gap = { 1 }
279
+ flex = { 1 }
280
+ alignItems = "flex-start"
281
+ >
317
282
{ platforms &&
318
283
platforms . map ( ( platform , idx ) => (
319
- < Pill type = "platform" key = { idx } >
284
+ < StakingPill type = "platform" key = { idx } >
320
285
{ platform }
321
- </ Pill >
286
+ </ StakingPill >
322
287
) ) }
323
288
{ ui &&
324
289
ui . map ( ( _ui , idx ) => (
325
- < Pill type = "ui" key = { idx } >
290
+ < StakingPill type = "ui" key = { idx } >
326
291
{ _ui }
327
- </ Pill >
292
+ </ StakingPill >
328
293
) ) }
329
- </ Pills >
330
- < Spacer />
331
- < Content >
332
- < ul >
294
+ </ Flex >
295
+ < Box { ...PADDED_DIV_STYLE } py = { 0 } >
296
+ < List m = { 0 } gap = { 3 } >
333
297
{ data &&
334
298
data . map ( ( { label, status } , idx ) => (
335
- < Item key = { idx } >
299
+ < ListItem
300
+ as = { Flex }
301
+ key = { idx }
302
+ textTransform = "uppercase"
303
+ fontSize = "xs"
304
+ lineHeight = "0.875rem"
305
+ letterSpacing = "wider"
306
+ my = { 4 }
307
+ ms = "auto"
308
+ me = { 0 }
309
+ py = { 2 }
310
+ gap = "1em"
311
+ alignItems = "center"
312
+ >
336
313
< Status status = { status } />
337
- < p > { label } </ p >
338
- </ Item >
314
+ { label }
315
+ </ ListItem >
339
316
) ) }
340
- </ ul >
341
- </ Content >
342
- < Cta >
343
- < ButtonLink to = { url } customEventOptions = { matomo } >
317
+ </ List >
318
+ </ Box >
319
+ < Box { ... PADDED_DIV_STYLE } >
320
+ < ButtonLink to = { url } customEventOptions = { matomo } width = "100%" >
344
321
< Translation id = "page-staking-products-get-started" />
345
322
</ ButtonLink >
346
- </ Cta >
347
- </ Card >
323
+ </ Box >
324
+ </ Flex >
348
325
)
349
326
}
350
327
@@ -353,11 +330,8 @@ export interface IProps {
353
330
}
354
331
355
332
const StakingProductCardGrid : React . FC < IProps > = ( { category } ) => {
356
- const theme = useTheme ( )
357
333
const [ rankedProducts , updateRankedProducts ] = useState < Array < Product > > ( [ ] )
358
- const isDarkTheme = theme . isDark
359
-
360
- const [ SAT , LUM ] = isDarkTheme ? [ "50%" , "35%" ] : [ "75%" , "60%" ]
334
+ const [ SAT , LUM ] = useColorModeValue ( [ "75%" , "60%" ] , [ "50%" , "35%" ] )
361
335
362
336
const scoreOpenSource = ( product : Product ) : 1 | 0 => {
363
337
return product . openSource === FlagType . VALID ? 1 : 0
@@ -564,11 +538,16 @@ const StakingProductCardGrid: React.FC<IProps> = ({ category }) => {
564
538
if ( ! rankedProducts ) return null
565
539
566
540
return (
567
- < CardGrid >
541
+ < SimpleGrid
542
+ templateColumns = "repeat(auto-fill, minmax(min(100%, 280px), 1fr))"
543
+ gap = { 8 }
544
+ my = { 12 }
545
+ mx = { 0 }
546
+ >
568
547
{ rankedProducts . map ( ( product ) => (
569
548
< StakingProductCard key = { product . name } product = { product } />
570
549
) ) }
571
- </ CardGrid >
550
+ </ SimpleGrid >
572
551
)
573
552
}
574
553
0 commit comments