1
- import { useEffect , useMemo , useState } from "react"
1
+ import React , { HTMLAttributes , useEffect , useMemo , useState } from "react"
2
2
import { GetStaticProps , InferGetServerSidePropsType } from "next"
3
3
import { useRouter } from "next/router"
4
4
import { useTranslation } from "next-i18next"
5
5
import { serverSideTranslations } from "next-i18next/serverSideTranslations"
6
6
import { FaGithub } from "react-icons/fa"
7
- import {
8
- Badge ,
9
- Box ,
10
- chakra ,
11
- Flex ,
12
- forwardRef ,
13
- Heading ,
14
- useToken ,
15
- } from "@chakra-ui/react"
7
+ import { Badge , chakra , forwardRef } from "@chakra-ui/react"
16
8
17
9
import { BasePageProps , Lang } from "@/lib/types"
18
10
19
- import { Button , ButtonLink } from "@/components/Buttons"
20
11
import Emoji from "@/components/Emoji"
21
12
import FeedbackCard from "@/components/FeedbackCard"
22
- import { BaseLink } from "@/components/Link "
13
+ import Heading from "@/components/Heading "
23
14
import MainArticle from "@/components/MainArticle"
24
- import OldHeading from "@/components/OldHeading"
25
- import Text from "@/components/OldText"
26
15
import PageMetadata from "@/components/PageMetadata"
27
16
import Translation from "@/components/Translation"
28
17
import { getSkillTranslationId , Skill } from "@/components/TutorialMetadata"
29
18
import TutorialTags from "@/components/TutorialTags"
19
+ import { Button , ButtonLink } from "@/components/ui/buttons/Button"
30
20
import Modal from "@/components/ui/dialog-modal"
21
+ import { Flex , FlexProps } from "@/components/ui/flex"
31
22
23
+ import { cn } from "@/lib/utils/cn"
32
24
import { existsNamespace } from "@/lib/utils/existsNamespace"
33
25
import { getLastDeployDate } from "@/lib/utils/getLastDeployDate"
34
26
import { trackCustomEvent } from "@/lib/utils/matomo"
@@ -43,7 +35,14 @@ import {
43
35
import externalTutorials from "@/data/externalTutorials.json"
44
36
45
37
import { useBreakpointValue } from "@/hooks/useBreakpointValue"
46
- import { useRtlFlip } from "@/hooks/useRtlFlip"
38
+
39
+ type Props = BasePageProps & {
40
+ internalTutorials : ITutorial [ ]
41
+ }
42
+
43
+ type LinkFlexProps = FlexProps & {
44
+ href : string
45
+ }
47
46
48
47
const FilterTag = forwardRef < { isActive : boolean ; name : string } , "button" > (
49
48
( props , ref ) => {
@@ -76,8 +75,16 @@ const FilterTag = forwardRef<{ isActive: boolean; name: string }, "button">(
76
75
}
77
76
)
78
77
79
- type Props = BasePageProps & {
80
- internalTutorials : ITutorial [ ]
78
+ const Text = ( { className, ...props } : HTMLAttributes < HTMLHeadElement > ) => (
79
+ < p className = { cn ( "mb-6" , className ) } { ...props } />
80
+ )
81
+
82
+ const LinkFlex = ( { href, children, ...props } : LinkFlexProps ) => {
83
+ return (
84
+ < Flex asChild { ...props } >
85
+ < a href = { href } > { children } </ a >
86
+ </ Flex >
87
+ )
81
88
}
82
89
83
90
export const getStaticProps = ( async ( { locale } ) => {
@@ -145,9 +152,6 @@ const TutorialPage = ({
145
152
contentNotTranslated,
146
153
} : InferGetServerSidePropsType < typeof getStaticProps > ) => {
147
154
const { locale } = useRouter ( )
148
- const { flipForRtl } = useRtlFlip ( )
149
- const tableBoxShadow = useToken ( "colors" , "tableBoxShadow" )
150
- const cardBoxShadow = useToken ( "colors" , "cardBoxShadow" )
151
155
const filteredTutorialsByLang = useMemo (
152
156
( ) =>
153
157
filterTutorialsByLang (
@@ -209,15 +213,8 @@ const TutorialPage = ({
209
213
210
214
const modalSize = useBreakpointValue ( { base : "xl" , md : "md" } as const )
211
215
return (
212
- < Flex
213
- as = { MainArticle }
214
- flexDirection = "column"
215
- alignItems = "center"
216
- w = "full"
217
- my = { 0 }
218
- mx = "auto"
219
- mt = { 16 }
220
- dir = { dir }
216
+ < MainArticle
217
+ className = { `mx-auto my-0 mt-16 flex w-full flex-col items-center ${ dir } ` }
221
218
>
222
219
< PageMetadata
223
220
title = { t ( "page-developers-tutorials:page-tutorials-meta-title" ) }
@@ -240,13 +237,7 @@ const TutorialPage = ({
240
237
>
241
238
< Translation id = "page-developers-tutorials:page-tutorial-title" />
242
239
</ Heading >
243
- < Text
244
- fontSize = "xl"
245
- lineHeight = "140%"
246
- color = "text200"
247
- mb = { 4 }
248
- textAlign = "center"
249
- >
240
+ < Text className = "mb-4 text-center leading-xs text-body-medium" >
250
241
< Translation id = "page-developers-tutorials:page-tutorial-subtitle" />
251
242
</ Text >
252
243
@@ -262,48 +253,28 @@ const TutorialPage = ({
262
253
< Text >
263
254
< Translation id = "page-developers-tutorials:page-tutorial-listing-policy-intro" />
264
255
</ Text >
265
- < Flex flexDirection = { { base : "column" , md : "row" } } gap = "2" >
266
- < Flex
267
- flex = "1"
268
- borderWidth = "1px"
269
- borderStyle = "solid"
270
- borderColor = "border"
271
- borderRadius = "base"
272
- p = { 4 }
273
- flexDirection = "column"
274
- justifyContent = "space-between"
275
- >
276
- < Text as = "b" >
256
+ < Flex className = "flex-col gap-2 md:flex-row" >
257
+ < Flex className = "w-full flex-col justify-between rounded-sm border border-border p-4" >
258
+ < b >
277
259
< Translation id = "page-developers-tutorials:page-tutorial-create-an-issue" />
278
- </ Text >
260
+ </ b >
279
261
< Text >
280
262
< Translation id = "page-developers-tutorials:page-tutorial-create-an-issue-desc" />
281
263
</ Text >
282
264
< ButtonLink
283
- leftIcon = { < FaGithub /> }
284
265
variant = "outline"
285
266
href = "https://github.com/ethereum/ethereum-org-website/issues/new?assignees=& labels = Type % 3 A + Feature & template = suggest_tutorial . yaml & title = "
286
267
>
268
+ < FaGithub />
287
269
< Translation id = "page-developers-tutorials:page-tutorial-raise-issue-btn" />
288
270
</ ButtonLink >
289
271
</ Flex >
290
272
</ Flex >
291
273
</ Modal >
292
274
293
275
< Button
276
+ className = "px-3 py-2 text-body"
294
277
variant = "outline"
295
- color = "text"
296
- borderColor = "text"
297
- _hover = { {
298
- color : "primary.base" ,
299
- borderColor : "primary.base" ,
300
- boxShadow : cardBoxShadow ,
301
- } }
302
- _active = { {
303
- bg : "secondaryButtonBackgroundActive" ,
304
- } }
305
- py = { 2 }
306
- px = { 3 }
307
278
onClick = { ( ) => {
308
279
setModalOpen ( true )
309
280
trackCustomEvent ( {
@@ -316,30 +287,9 @@ const TutorialPage = ({
316
287
< Translation id = "page-developers-tutorials:page-tutorial-submit-btn" />
317
288
</ Button >
318
289
319
- < Box
320
- boxShadow = { tableBoxShadow }
321
- mb = { 8 }
322
- mt = { 8 }
323
- w = { { base : "full" , md : "66%" } }
324
- >
325
- < Flex
326
- justifyContent = "center"
327
- m = { 8 }
328
- pb = { { base : 4 , md : 8 } }
329
- pt = { { base : 4 , md : "initial" } }
330
- px = { { base : 0 , md : "initial" } }
331
- borderBottomWidth = "1px"
332
- borderBottomStyle = "solid"
333
- borderBottomColor = "border"
334
- flexDirection = { { base : "column" , md : "initial" } }
335
- >
336
- < Flex
337
- flexWrap = "wrap"
338
- alignItems = "center"
339
- gap = { 2 }
340
- maxW = { { base : "full" , md : "initial" } }
341
- mb = { { base : 4 , md : "initial" } }
342
- >
290
+ < div className = "my-8 w-full shadow-table-box md:w-2/3" >
291
+ < Flex className = "m-8 flex-col justify-center border-b border-border px-0 pb-4 pt-4 md:pb-8" >
292
+ < Flex className = "mb-4 max-w-full flex-wrap items-center gap-2" >
343
293
{ Object . entries ( allTags ) . map ( ( [ tagName , tagCount ] , idx ) => {
344
294
const name = `${ tagName } (${ tagCount } )`
345
295
const isActive = selectedTags . includes ( tagName )
@@ -353,15 +303,8 @@ const TutorialPage = ({
353
303
} ) }
354
304
{ selectedTags . length > 0 && (
355
305
< Button
356
- color = "primary.base"
357
- textDecoration = "underline"
358
- bg = "none"
359
- border = "none"
360
- cursor = "pointer"
361
- p = { 0 }
362
- _hover = { {
363
- bg : "none" ,
364
- } }
306
+ className = "cursor-pointer p-0 text-primary underline"
307
+ variant = "ghost"
365
308
onClick = { ( ) => {
366
309
setSelectedTags ( [ ] )
367
310
trackCustomEvent ( {
@@ -377,69 +320,37 @@ const TutorialPage = ({
377
320
</ Flex >
378
321
</ Flex >
379
322
{ filteredTutorials . length === 0 && (
380
- < Box mt = { 0 } textAlign = " center" padding = { 12 } >
323
+ < div className = "mt-0 p-12 text- center">
381
324
< Emoji text = ":crying_face:" className = "my-8 text-5xl" />
382
- < OldHeading >
325
+ < h2 className = "mb-8 mt-12 leading-xs" >
383
326
< Translation id = "page-developers-tutorials:page-tutorial-tags-error" />
384
- </ OldHeading >
327
+ </ h2 >
385
328
< Text >
386
329
< Translation id = "page-developers-tutorials:page-find-wallet-try-removing" />
387
330
</ Text >
388
- </ Box >
331
+ </ div >
389
332
) }
390
333
{ filteredTutorials . map ( ( tutorial ) => {
391
334
return (
392
- < Flex
393
- as = { BaseLink }
394
- textDecoration = "none"
395
- flexDirection = "column"
396
- justifyContent = "space-between"
397
- fontWeight = "normal"
398
- color = "text"
399
- boxShadow = "0px 1px 1px var(--eth-colors-tableItemBoxShadow)"
400
- mb = "px"
401
- padding = { 8 }
402
- w = "full"
403
- _hover = { {
404
- textDecoration : "none" ,
405
- borderRadius : "base" ,
406
- boxShadow : "0 0 1px var(--eth-colors-primary-base)" ,
407
- bg : "tableBackgroundHover" ,
408
- } }
335
+ < LinkFlex
336
+ className = "mb-px w-full flex-col justify-between border-b p-8 text-border no-underline duration-100 hover:bg-background-highlight"
409
337
key = { tutorial . href }
410
338
href = { tutorial . href ?? undefined }
411
- hideArrow
412
339
>
413
- < Flex
414
- justifyContent = "space-between"
415
- mb = { { base : 8 , md : - 4 } }
416
- alignItems = "flex-start"
417
- flexDirection = { { base : "column" , md : "initial" } }
418
- >
340
+ < Flex className = "mb-8 flex-col items-start justify-between gap-y-4 md:-mb-4 md:flex-row" >
419
341
< Text
420
- color = "text"
421
- fontWeight = "semibold"
422
- fontSize = "2xl"
423
- me = { { base : 0 , md : 24 } }
424
- _after = { {
425
- ms : 0.5 ,
426
- me : "0.3rem" ,
427
- display : tutorial . isExternal ? "inline-block" : "none" ,
428
- content : `"↗"` ,
429
- transform : flipForRtl ,
430
- transitionProperty : "all" ,
431
- transitionDuration : "0.1s" ,
432
- transitionTimingFunction : "ease-in-out" ,
433
- fontStyle : "normal" ,
434
- } }
342
+ className = { cn (
343
+ "relative me-0 text-2xl font-semibold text-body after:ml-2 after:inline-block after:italic after:transition-all after:duration-100 after:ease-in-out after:content-['↗'] md:me-24" ,
344
+ tutorial . isExternal ? "after:inline-block" : "after:hidden"
345
+ ) }
435
346
>
436
347
{ tutorial . title }
437
348
</ Text >
438
349
< Badge variant = "secondary" >
439
350
< Translation id = { getSkillTranslationId ( tutorial . skill ! ) } />
440
351
</ Badge >
441
352
</ Flex >
442
- < Text color = "text200" fontSize = "sm" textTransform = " uppercase">
353
+ < Text className = "mt-6 uppercase text-body-medium ">
443
354
< Emoji text = ":writing_hand:" className = "me-2 text-sm" />
444
355
{ tutorial . author }
445
356
{ tutorial . published ? (
@@ -458,22 +369,22 @@ const TutorialPage = ({
458
369
< >
459
370
{ " " }
460
371
•< Emoji text = ":link:" className = "mx-2 text-sm" />
461
- < Box as = " span" color = "primary.base" cursor = " pointer">
372
+ < span className = " cursor- pointer text-primary ">
462
373
< Translation id = "page-developers-tutorials:page-tutorial-external-link" />
463
- </ Box >
374
+ </ span >
464
375
</ >
465
376
) }
466
377
</ Text >
467
- < Text color = "text200 "> { tutorial . description } </ Text >
468
- < Flex flexWrap = "wrap" w = " full">
378
+ < Text className = "text-body-medium "> { tutorial . description } </ Text >
379
+ < Flex className = "w- full flex-wrap ">
469
380
< TutorialTags tags = { tutorial . tags ?? [ ] } />
470
381
</ Flex >
471
- </ Flex >
382
+ </ LinkFlex >
472
383
)
473
384
} ) }
474
- </ Box >
385
+ </ div >
475
386
< FeedbackCard />
476
- </ Flex >
387
+ </ MainArticle >
477
388
)
478
389
}
479
390
0 commit comments