@@ -3,14 +3,20 @@ import React, { useEffect, useState, Fragment } from 'react'
33import "./App.css"
44import Api from "./Services/Api" ;
55import 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" ;
88
99const App = ( ) => {
1010
11+ // Use state to show initial loading skeleton state.
12+ const [ loading , setLoading ] = useState ( true ) ;
13+
1114 // Use state to store the users data from the API call and set it to an empty array initially.
1215 const [ users , setUsers ] = useState ( [ ] ) ;
1316
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+
1420 // Use state to store the edited user data and set it to an empty object initially.
1521 const [ editUserForm , setEditUserForm ] = useState ( {
1622 id : '' ,
@@ -34,8 +40,12 @@ const App = () => {
3440 // Get the users from the API when the component mounts and set the users to the state using the setUsers() method.
3541 useEffect ( ( ) => {
3642 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 ) ) ;
3949 } , [ ] ) ; // [] is used to tell React that this effect should only run once.
4050
4151 // 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 = () => {
8393 const currentItems = filteredUsers . slice ( indexOfFirstItem , indexOfLastItem ) ; // Get the users in the current page.
8494
8595 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 />
95108 </ 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
121137 ? currentItems
122138 . map ( ( user , index ) => (
123139 < Fragment key = { index } >
@@ -149,22 +165,22 @@ const App = () => {
149165 </ div >
150166 </ td >
151167 </ 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+
168184 </ div >
169185 </ div >
170186 )
0 commit comments