@@ -3,14 +3,20 @@ import React, { useEffect, useState, Fragment } from 'react'
3
3
import "./App.css"
4
4
import Api from "./Services/Api" ;
5
5
import ThemeToggle from "./Components/DarkMode/ThemeToggle" ;
6
- import { DeleteSelectedBtn , SearchUser , EditableRow , DisplayRows , Pagination } from "./Components" ;
7
- import icon from "./icon.png" ;
6
+ import { DeleteSelectedBtn , SearchUser , EditableRow , DisplayRows , Pagination , Modal , Skeleton } from "./Components" ;
7
+ import icon from "./Images/ icon.png" ;
8
8
9
9
const App = ( ) => {
10
10
11
+ // Use state to show initial loading skeleton state.
12
+ const [ loading , setLoading ] = useState ( true ) ;
13
+
11
14
// Use state to store the users data from the API call and set it to an empty array initially.
12
15
const [ users , setUsers ] = useState ( [ ] ) ;
13
16
17
+ // Use state to set the error to be true if the API call fails and set it to false if the API call succeeds.
18
+ const [ error , setError ] = useState ( false ) ;
19
+
14
20
// Use state to store the edited user data and set it to an empty object initially.
15
21
const [ editUserForm , setEditUserForm ] = useState ( {
16
22
id : '' ,
@@ -34,8 +40,12 @@ const App = () => {
34
40
// Get the users from the API when the component mounts and set the users to the state using the setUsers() method.
35
41
useEffect ( ( ) => {
36
42
Api . getUsers ( )
37
- . then ( data => setUsers ( data ) )
38
- . catch ( error => console . log ( error ) ) ;
43
+ . then ( data => {
44
+ setError ( false )
45
+ setUsers ( data )
46
+ } )
47
+ . catch ( error => setError ( true ) )
48
+ . finally ( setLoading ( false ) ) ;
39
49
} , [ ] ) ; // [] is used to tell React that this effect should only run once.
40
50
41
51
// Checked all the users in the current page and set the users to the state using the setUsers() method.
@@ -83,41 +93,47 @@ const App = () => {
83
93
const currentItems = filteredUsers . slice ( indexOfFirstItem , indexOfLastItem ) ; // Get the users in the current page.
84
94
85
95
return (
86
- < div className = "min-h-screen min-w-screen bg-background dark:bg-background-dark dark:text-white transition-all ease-out text-gray text-center flex justify-center items-center overflow-hidden" >
87
- < div className = " h-full sm:h-auto w-full sm:w-auto mt-0 sm:mt-4 px-2 sm:px-8 text-sm md:text-md" >
88
-
89
- < div className = "py-1 pt-0 w-full flex justify-between items-center" >
90
- < DeleteSelectedBtn users = { users } setUsers = { setUsers } />
91
- < div className = "flex justify-center items-center" >
92
- < SearchUser searchResult = { searchResult } setSearchResult = { setSearchResult } />
93
- < ThemeToggle />
94
- </ div >
96
+ < div className = "relative min-h-screen min-w-screen bg-background dark:bg-background-dark dark:text-white transition-all ease-out text-gray text-center flex justify-center items-center overflow-hidden" >
97
+ < div className = "h-full sm:h-auto w-full sm:w-auto mt-0 sm:mt-4 px-2 sm:px-8 text-sm md:text-md" >
98
+
99
+ {
100
+ error && < Modal />
101
+ }
102
+
103
+ < div className = "py-1 pt-0 w-full flex justify-between items-center" >
104
+ < DeleteSelectedBtn users = { users } setUsers = { setUsers } />
105
+ < div className = "flex justify-center items-center" >
106
+ < SearchUser searchResult = { searchResult } setSearchResult = { setSearchResult } />
107
+ < ThemeToggle />
95
108
</ div >
96
-
97
- < div className = "flex flex-col mt-1 min-h-[75vh] min-w-auto md:min-w-[75vw] xl:min-w-[55vw]" >
98
- < div className = "py-2 pb-0 overflow-auto" >
99
- < form onSubmit = { handleUserEditFormSubmit } >
100
- < table className = "w-full sm:min-w-full table-auto" >
101
- < thead className = "relative" >
102
- < tr className = "text-md font-medium text-gray-deep uppercase tracking-wider" >
103
- < th scope = "col" className = "px-6 py-2 w-auto text-center" >
104
- < input
105
- type = "checkbox"
106
- value = "checkedAll"
107
- className = "form-checkbox h-4 w-4"
108
- onChange = { handleAllChecked }
109
- checked = { users . slice ( indexOfFirstItem , indexOfLastItem ) . filter ( user => user ?. isChecked !== true ) . length < 1 }
110
- />
111
- </ th >
112
- < th scope = "col" className = "px-6 py-2 text-left" > Name</ th >
113
- < th scope = "col" className = "px-6 py-2 text-left" > Email</ th >
114
- < th scope = "col" className = "px-6 py-2 text-left" > Role</ th >
115
- < th scope = "col" className = "px-6 py-2 text-center" > Action</ th >
116
- </ tr >
117
- </ thead >
118
- < tbody className = "relative text-md divide-y-4 divide-transparent" >
119
- {
120
- users && users . length > 0 && filteredUsers . length > 0
109
+ </ div >
110
+
111
+ < div className = "flex flex-col mt-1 min-h-[75vh] min-w-auto md:min-w-[75vw] xl:min-w-[55vw]" >
112
+ < div className = "py-2 pb-0 overflow-auto" >
113
+ < form onSubmit = { handleUserEditFormSubmit } >
114
+ < table className = "w-full sm:min-w-full table-auto" >
115
+ < thead className = "relative" >
116
+ < tr className = "text-md font-medium text-gray-deep uppercase tracking-wider" >
117
+ < th scope = "col" className = "px-6 py-2 w-auto text-center" >
118
+ < input
119
+ type = "checkbox"
120
+ value = "checkedAll"
121
+ className = "form-checkbox h-4 w-4"
122
+ onChange = { handleAllChecked }
123
+ checked = { users . slice ( indexOfFirstItem , indexOfLastItem ) . filter ( user => user ?. isChecked !== true ) . length < 1 }
124
+ />
125
+ </ th >
126
+ < th scope = "col" className = "px-6 py-2 text-left" > Name</ th >
127
+ < th scope = "col" className = "px-6 py-2 text-left" > Email</ th >
128
+ < th scope = "col" className = "px-6 py-2 text-left" > Role</ th >
129
+ < th scope = "col" className = "px-6 py-2 text-center" > Action</ th >
130
+ </ tr >
131
+ </ thead >
132
+ < tbody className = "relative text-md divide-y-4 divide-transparent" >
133
+ {
134
+ loading
135
+ ? < Skeleton />
136
+ : users && users . length > 0 && filteredUsers . length > 0
121
137
? currentItems
122
138
. map ( ( user , index ) => (
123
139
< Fragment key = { index } >
@@ -149,22 +165,22 @@ const App = () => {
149
165
</ div >
150
166
</ td >
151
167
</ tr >
152
- }
153
- </ tbody >
154
- </ table >
155
- </ form >
156
- </ div >
157
- </ div >
158
-
159
- < div className = { `${ users . length !== 0 ? 'flex' : 'invisible' } justify-center items-center py-2 md:py-6` } >
160
- < Pagination
161
- filteredUsers = { filteredUsers }
162
- itemPerPage = { itemPerPage }
163
- currentPage = { currentPage }
164
- setCurrentPage = { setCurrentPage }
165
- />
166
- </ div >
167
-
168
+ }
169
+ </ tbody >
170
+ </ table >
171
+ </ form >
172
+ </ div >
173
+ </ div >
174
+
175
+ < div className = { `${ users . length !== 0 ? 'flex' : 'invisible' } justify-center items-center py-2 md:py-6` } >
176
+ < Pagination
177
+ filteredUsers = { filteredUsers }
178
+ itemPerPage = { itemPerPage }
179
+ currentPage = { currentPage }
180
+ setCurrentPage = { setCurrentPage }
181
+ />
182
+ </ div >
183
+
168
184
</ div >
169
185
</ div >
170
186
)
0 commit comments