1
- import formatString from "@/app/functions/formatString" ;
1
+ "use client" ;
2
+
3
+ import { useEffect , useState } from "react" ;
4
+ import { collection , getDocs } from "firebase/firestore" ;
5
+ import { db } from "@/lib/firebase" ;
2
6
import Link from "next/link" ;
3
7
import Image from "next/image" ;
4
- import { db } from "@/lib/firebase" ;
5
- import { collection , getDocs , orderBy } from "firebase/firestore" ;
8
+ import { RiArrowRightLine } from "react-icons/ri" ;
9
+ import { Skeleton } from "./ui/skeleton" ;
10
+ import SkeletonCard from "./Authors/SkeletonCard" ; // Import the same SkeletonCard used in latest posts
6
11
12
+ // Define the structure of an author
7
13
type AuthorType = {
8
14
uid : string ;
9
15
name : string ;
@@ -14,58 +20,73 @@ type AuthorType = {
14
20
slug : string ;
15
21
} ;
16
22
17
- export default async function AuthorsList ( ) {
18
- // Fetch authors from Firestore
19
- const querySnapshot = await getDocs (
20
- collection ( db , "authors" )
21
- ) ;
22
-
23
- const authors = querySnapshot . docs . map ( doc => ( {
24
- uid : doc . id ,
25
- ...doc . data ( )
26
- } ) ) as AuthorType [ ] ;
23
+ export default function AuthorsList ( ) {
24
+ const [ authors , setAuthors ] = useState < AuthorType [ ] > ( [ ] ) ;
25
+ const [ loading , setLoading ] = useState ( true ) ;
26
+
27
+ useEffect ( ( ) => {
28
+ const fetchAuthors = async ( ) => {
29
+ const querySnapshot = await getDocs ( collection ( db , "authors" ) ) ;
30
+ const fetchedAuthors = querySnapshot . docs . map ( ( doc ) => ( {
31
+ ...( doc . data ( ) as Omit < AuthorType , "uid" > ) ,
32
+ uid : doc . id ,
33
+ } ) ) ;
34
+
35
+ setAuthors ( fetchedAuthors ) ;
36
+ setLoading ( false ) ;
37
+ } ;
38
+
39
+ fetchAuthors ( ) ;
40
+ } , [ ] ) ;
27
41
28
42
return (
29
43
< div className = "flex flex-col max-w-[95rem] w-full mx-auto py-8 lg:pt-24 lg:pb-48" >
30
- { authors . map ( ( author , index ) => (
31
- < div key = { author . uid } >
32
- < article className = "flex flex-col md:flex-row justify-between md:items-center gap-2 md:gap-0" >
33
- < div className = "flex flex-col md:flex-row md:items-center gap-2 md:gap-16" >
34
- < Image
35
- className = "h-[9.375rem] w-[9.375rem]"
36
- src = { author . avatar }
37
- alt = { author . imgAlt }
38
- width = { 150 }
39
- height = { 150 }
40
- />
41
- < h2 className = "heading3-title" > { author . name } </ h2 >
42
- </ div >
43
- < div className = "flex flex-col lg:flex-row gap-2 lg:gap-24" >
44
- < div className = "flex gap-2" >
45
- < p className = "font-semibold" > Job</ p >
46
- < p > { author . job } </ p >
44
+ { loading ? (
45
+ // Skeleton Loader (Using the same structure as LatestPosts)
46
+ < div className = "grid gap-6" >
47
+ { [ ...Array ( 6 ) ] . map ( ( _ , index ) => (
48
+ < SkeletonCard key = { index } />
49
+ ) ) }
50
+ </ div >
51
+ ) : (
52
+ authors . map ( ( author , index ) => (
53
+ < div key = { author . uid } >
54
+ < article className = "flex flex-col md:flex-row justify-between md:items-center gap-4 ml-5" >
55
+ < div className = "flex flex-col md:flex-row md:items-center gap-4 md:gap-16" >
56
+ { /* Ensure image has a transparent background */ }
57
+ < Image
58
+ className = "h-[9.375rem] w-[9.375rem] object-cover rounded-full bg-transparent"
59
+ src = { author . avatar }
60
+ alt = { author . imgAlt }
61
+ width = { 150 }
62
+ height = { 150 }
63
+ />
64
+ < Link href = { `authors/${ author . slug } ` } >
65
+ < h2 className = "text-2xl font-semibold" > { author . name } </ h2 >
66
+ </ Link >
47
67
</ div >
48
- < div className = "flex gap-2" >
49
- < p className = "font-semibold" > City</ p >
50
- < p > { author . city } </ p >
68
+ < div className = "flex flex-col lg:flex-row gap-4 lg:gap-24" >
69
+ < div className = "flex gap-2" >
70
+ < p className = "font-semibold" > Job:</ p >
71
+ < p > { author . job } </ p >
72
+ </ div >
73
+ < div className = "flex gap-2" >
74
+ < p className = "font-semibold" > City:</ p >
75
+ < p > { author . city } </ p >
76
+ </ div >
77
+ < Link
78
+ className = "flex items-center gap-2 text-white hover:text-[#8a2be2] transition ease-in-out duration-300"
79
+ href = { `authors/${ author . slug } ` }
80
+ >
81
+ < span className = "uppercase font-semibold" > About</ span >
82
+ < RiArrowRightLine className = "text-2xl" />
83
+ </ Link >
51
84
</ div >
52
- < Link
53
- className = "flex gap-2"
54
- href = { `authors/${ author . slug } ` }
55
- >
56
- < span className = "uppercase font-semibold" > About</ span >
57
- < img
58
- src = "/icons/ri_arrow-right-line.svg"
59
- alt = "An arrow pointing right"
60
- />
61
- </ Link >
62
- </ div >
63
- </ article >
64
- { index < authors . length - 1 && (
65
- < div className = "border border-black my-6" />
66
- ) }
67
- </ div >
68
- ) ) }
85
+ </ article >
86
+ { index < authors . length - 1 && < div className = "border border-gray-300 my-10" /> }
87
+ </ div >
88
+ ) )
89
+ ) }
69
90
</ div >
70
91
) ;
71
- }
92
+ }
0 commit comments