1
+ import { createDefaultImageCover } from "@/lib/utils" ;
1
2
import Image from "next/image" ;
2
3
import Link from "next/link" ;
3
4
4
- async function getData ( ) {
5
+ interface BlogData {
6
+ cover_image : string ;
7
+ title : string ;
8
+ description : string ;
9
+ url : string ;
10
+ user : {
11
+ username : string ;
12
+ }
13
+ }
14
+
15
+ async function getData ( ) : Promise < BlogData [ ] > {
5
16
const res = await fetch ( "https://dev.to/api/articles?username=webxdao" ) ;
6
- // The return value is *not* serialized
7
- // You can return Date, Map, Set, etc.
8
17
9
- // Recommendation: handle errors
10
18
if ( ! res . ok ) {
11
- // This will activate the closest `error.js` Error Boundary
12
19
throw new Error ( "Failed to fetch data" ) ;
13
20
}
14
21
@@ -17,59 +24,62 @@ async function getData() {
17
24
18
25
export default async function Blog ( ) {
19
26
// Initiate dev.to API request
20
- const blogData = getData ( ) ;
21
-
22
- // Wait for the promises to resolve
23
- const [ dataT ] = await Promise . all ( [ blogData ] ) ;
27
+ const blogData : BlogData [ ] = await getData ( ) ;
24
28
25
29
return (
26
30
< section className = "mt-20" >
27
31
< div className = "mx-auto max-w-5xl md:px-8" >
28
- < h1 className = "mt-10 text-xl font-bold" > Get to know more</ h1 >
32
+ < h1 className = "mt-10 text-center text-2xl font-bold" > Get to know more</ h1 >
29
33
< p className = "mx-auto mt-5 max-w-sm text-center md:max-w-xl lg:max-w-3xl" >
30
34
Discover the exciting world of blockchain technology as we come together to collaborate
31
35
and expand our knowledge.
32
36
</ p >
33
37
</ div >
34
38
< div className = "mt-10 flex flex-wrap justify-center gap-16" >
35
- { dataT . map ( ( curElem : any ) => (
36
- < div className = "bg-whie flex max-w-xs flex-col rounded-lg bg-white/5 p-2 shadow-md shadow-purple-400/40 transition-all duration-200 ease-in hover:z-50 hover:shadow-lg hover:shadow-purple-400/60 sm:hover:-translate-y-1" >
37
- < Image
38
- className = "w-full rounded-md border"
39
- src = { curElem . cover_image }
40
- width = { 400 }
41
- height = { 250 }
42
- alt = ""
43
- />
44
- < div className = "grow px-6 py-4" >
45
- < h3 className = "mb-4 text-center text-sm font-bold uppercase leading-4 tracking-wider" >
46
- { curElem . title }
47
- </ h3 >
48
- < p className = "text-justify text-sm text-gray-700 dark:text-gray-300" >
49
- { curElem . description }
50
- </ p >
51
- </ div >
52
- < div className = "flex px-6 py-4" >
53
- < Link
54
- href = { curElem . url }
55
- target = "_blank"
56
- className = "w-fit-content font-inter text-14.0418 group mb-0 mr-auto flex items-center gap-6 rounded border-2 border-solid border-black px-4 py-1 text-black transition delay-0 ease-in hover:border-slate-500 hover:bg-slate-500 hover:font-semibold dark:border-white/80 dark:text-white dark:hover:border-slate-500"
57
- >
58
- < Image
59
- src = "/Arrow1.png"
60
- alt = "arrow"
61
- width = { 15 }
62
- height = { 15 }
63
- className = "my-auto flex items-center transition duration-100 ease-in group-hover:invert dark:invert"
64
- />
65
- < span className = "transition duration-100 ease-in group-hover:text-white" >
66
- Read More
67
- </ span >
68
- </ Link >
69
- </ div >
70
- </ div >
39
+ { blogData . map ( ( data ) => (
40
+ < BCard key = { data . title } data = { data } />
71
41
) ) }
72
42
</ div >
73
43
</ section >
74
44
) ;
75
45
}
46
+
47
+ function BCard ( { data } : { data : BlogData } ) {
48
+ const imgSrc = data . cover_image ?? createDefaultImageCover ( {
49
+ title : data . title ,
50
+ username : data . user . username ,
51
+ } ) ;
52
+ return (
53
+ < div className = "flex max-w-xs flex-col rounded-lg border bg-white/5 p-2 shadow-md shadow-purple-400/40 transition-transform duration-200 ease-in hover:z-50 hover:shadow-lg hover:shadow-purple-400/60 sm:hover:-translate-y-1" >
54
+ < Image
55
+ className = "h-36 w-full rounded-md border"
56
+ src = { imgSrc }
57
+ alt = { data . title }
58
+ width = { 400 }
59
+ height = { 250 }
60
+ />
61
+ < div className = "grow px-6 py-4" >
62
+ < h3 className = "mb-4 text-center text-sm font-bold uppercase leading-4 tracking-wider" >
63
+ { data . title }
64
+ </ h3 >
65
+ < p className = "text-justify text-sm text-gray-700 dark:text-gray-300" > { data . description } </ p >
66
+ </ div >
67
+ < div className = "flex px-6 py-4" >
68
+ < Link
69
+ href = { data . url }
70
+ target = "_blank"
71
+ className = "w-fit-content font-inter text-14.0418 group mb-0 mr-auto flex items-center gap-6 rounded border-2 border-solid border-black px-4 py-1 text-black transition delay-0 ease-in hover:border-slate-500 hover:bg-slate-500 hover:font-semibold dark:border-white/80 dark:text-white dark:hover:border-slate-500"
72
+ >
73
+ < Image
74
+ src = "/Arrow1.png"
75
+ alt = "arrow"
76
+ width = { 15 }
77
+ height = { 15 }
78
+ className = "my-auto flex items-center transition duration-100 ease-in group-hover:invert dark:invert"
79
+ />
80
+ < span className = "transition duration-100 ease-in group-hover:text-white" > Read More</ span >
81
+ </ Link >
82
+ </ div >
83
+ </ div >
84
+ ) ;
85
+ }
0 commit comments