1
1
import React from 'react' ;
2
2
import Search from './components/Search' ;
3
3
import UserCard from './components/UserCard' ;
4
+ import RepoCard from './components/RepoCard' ;
5
+
6
+ const PAGE_SIZE = 30 ;
4
7
5
8
class App extends React . Component {
6
9
state = {
7
10
user : null ,
8
- error : null ,
11
+ repos : [ ] ,
12
+ userDataError : null ,
9
13
loading : false ,
14
+ page : 1 ,
10
15
} ;
11
16
12
17
fetchUserData = async username => {
18
+ const res = await fetch ( `https://api.github.com/users/${ username } ` ) ;
19
+ if ( res . ok ) {
20
+ const data = await res . json ( ) ;
21
+
22
+ return { data } ;
23
+ }
24
+
25
+ const error = ( await res . json ( ) ) . message ;
26
+
27
+ return { error } ;
28
+ } ;
29
+
30
+ fetchRepos = async username => {
31
+ const { page } = this . state ;
32
+ const res = await fetch (
33
+ `https://api.github.com/users/${ username } /repos?page=${ page } &per_page=${ PAGE_SIZE } ` ,
34
+ ) ;
35
+ if ( res . ok ) {
36
+ const data = await res . json ( ) ;
37
+
38
+ return { data, page : page + 1 } ;
39
+ }
40
+
41
+ const error = ( await res . json ( ) ) . message ;
42
+
43
+ return { error } ;
44
+ } ;
45
+
46
+ fetchData = async username => {
13
47
this . setState ( { loading : true } , async ( ) => {
14
48
try {
15
- const res = await fetch ( `https://api.github.com/users/${ username } ` ) ;
16
- if ( res . ok ) {
17
- const data = await res . json ( ) ;
49
+ const [ user , repos ] = await Promise . all ( [
50
+ this . fetchUserData ( username ) ,
51
+ this . fetchRepos ( username ) ,
52
+ ] ) ;
18
53
54
+ if ( user . data !== undefined && repos . data !== undefined ) {
19
55
return this . setState ( {
20
- user : data ,
56
+ user : user . data ,
57
+ repos : repos . data ,
58
+ page : repos . page ,
21
59
loading : false ,
22
60
} ) ;
23
61
}
24
62
25
- const error = ( await res . json ( ) ) . message ;
26
-
27
63
this . setState ( {
28
- error,
64
+ userDataError : user . error ,
65
+ reposError : repos . error ,
29
66
loading : false ,
30
67
} ) ;
31
68
} catch ( err ) {
@@ -37,18 +74,49 @@ class App extends React.Component {
37
74
} ) ;
38
75
} ;
39
76
77
+ loadMore = async ( ) => {
78
+ const { data, page } = await this . fetchRepos ( this . state . user . login ) ;
79
+
80
+ if ( data )
81
+ this . setState ( state => ( {
82
+ repos : [ ...state . repos , ...data ] ,
83
+ page,
84
+ } ) ) ;
85
+ } ;
86
+
40
87
render ( ) {
41
- const { error, loading, user } = this . state ;
88
+ const {
89
+ userDataError,
90
+ reposError,
91
+ loading,
92
+ user,
93
+ repos,
94
+ page,
95
+ } = this . state ;
42
96
43
97
return (
44
98
< div >
45
- < Search fetchData = { this . fetchUserData } />
99
+ < Search fetchData = { this . fetchData } />
46
100
< div className = "container" >
47
101
< div className = "text-center pt-5" >
48
102
{ loading && < p > Loading...</ p > }
49
- { error && < p className = "text-danger" > { error } </ p > }
103
+ { userDataError && < p className = "text-danger" > { userDataError } </ p > }
50
104
</ div >
51
- { ! loading && ! error && user && < UserCard user = { user } /> }
105
+ { ! loading && ! userDataError && user && < UserCard user = { user } /> }
106
+ { reposError && < p className = "text-danger" > { reposError } </ p > }
107
+
108
+ { ! loading &&
109
+ ! reposError &&
110
+ repos . map ( repo => < RepoCard key = { repo . id } repo = { repo } /> ) }
111
+
112
+ { ! loading &&
113
+ ! userDataError &&
114
+ user &&
115
+ ( page - 1 ) * PAGE_SIZE < user . public_repos && (
116
+ < button className = "btn btn-success" onClick = { this . loadMore } >
117
+ Load More
118
+ </ button >
119
+ ) }
52
120
</ div >
53
121
</ div >
54
122
) ;
0 commit comments