1
+ /**
2
+ * React component representing the main application.
3
+ * @extends Component
4
+ */
1
5
import { Component } from 'react' ;
6
+
7
+ // Importing the fetchImages function from the services/api module
8
+ import fetchImages from 'services/api' ;
9
+
10
+ // Importing various React components for the application
2
11
import Searchbar from './Searchbar' ;
3
12
import ImageGallery from './ImageGallery' ;
4
13
import ImagePortalWelcome from './ImagePortalWelcome' ;
5
- import { LoadMoreBtn } from './Button' ;
6
- import { SearchResultInfo } from './SearchResultInfo' ;
14
+ import LoadMoreBtn from './Button' ;
15
+ import SearchResultInfo from './SearchResultInfo' ;
7
16
import ErrorAlert from './ErrorAlert' ;
8
17
import NoResultsAlert from './NoResultsAlert' ;
18
+ import Loader from './Loader' ;
9
19
10
- import { Container } from 'react-bootstrap' ;
11
-
12
- import fetchImages from 'services/api' ;
13
-
20
+ // Importing Bootstrap styles and components
14
21
import 'bootstrap/dist/css/bootstrap.min.css' ;
15
- import { Loader } from './Loader ' ;
22
+ import { Container } from 'react-bootstrap ' ;
16
23
24
+ /**
25
+ * Main App component representing the image search application.
26
+ * @class
27
+ */
17
28
class App extends Component {
18
- constructor ( props ) {
19
- super ( props ) ;
20
-
21
- this . state = {
22
- images : [ ] ,
23
- searchQuery : '' ,
24
- currentPage : 1 ,
25
- isLoading : false ,
26
- error : null ,
27
- totalHits : null ,
28
- } ;
29
- }
29
+ /**
30
+ * State of the App component.
31
+ * @type {Object }
32
+ * @property {Array } images - Array to store fetched images.
33
+ * @property {string } searchQuery - Current search query.
34
+ * @property {number } currentPage - Current page number for paginated results.
35
+ * @property {boolean } isLoading - Flag indicating whether images are being loaded.
36
+ * @property {string|null } error - Error message if image fetching fails.
37
+ * @property {number|null } totalHits - Total number of hits for the current search query.
38
+ */
39
+ state = {
40
+ images : [ ] ,
41
+ searchQuery : '' ,
42
+ currentPage : 1 ,
43
+ isLoading : false ,
44
+ error : null ,
45
+ totalHits : null ,
46
+ } ;
30
47
48
+ /**
49
+ * Fetches images from the Pixabay API based on the current search query and page number.
50
+ * Updates the component state accordingly.
51
+ * @async
52
+ * @function
53
+ * @returns {Promise<void> }
54
+ */
31
55
getImages = async ( ) => {
32
56
const { searchQuery, currentPage } = this . state ;
33
57
58
+ // If there is no search query, return early
34
59
if ( ! searchQuery ) {
35
60
return ;
36
61
}
37
62
38
63
try {
64
+ // Set loading state to true
39
65
this . setState ( {
40
66
isLoading : true ,
41
67
} ) ;
42
68
69
+ // Fetch images from Pixabay API
43
70
const { hits, totalHits } = await fetchImages ( searchQuery , currentPage ) ;
44
71
45
72
// Append new images to the existing ones
@@ -49,16 +76,25 @@ class App extends Component {
49
76
totalHits : totalHits || 0 ,
50
77
} ) ) ;
51
78
} catch ( error ) {
79
+ // Handle errors by setting the error state
52
80
this . setState ( {
53
81
error : error . message ,
54
82
} ) ;
55
83
} finally {
84
+ // Set loading state to false regardless of success or failure
56
85
this . setState ( {
57
86
isLoading : false ,
58
87
} ) ;
59
88
}
60
89
} ;
61
90
91
+ /**
92
+ * Lifecycle method that gets called whenever the component updates.
93
+ * Calls the getImages method if the searchQuery or currentPage changes.
94
+ * @param {Object } _prevProps - Previous properties.
95
+ * @param {Object } prevState - Previous state.
96
+ * @returns {Promise<void> }
97
+ */
62
98
async componentDidUpdate ( _prevProps , prevState ) {
63
99
if (
64
100
prevState . searchQuery !== this . state . searchQuery ||
@@ -68,12 +104,22 @@ class App extends Component {
68
104
}
69
105
}
70
106
107
+ /**
108
+ * Updates the currentPage in the state, triggering a new set of images to be fetched.
109
+ * @function
110
+ * @returns {void }
111
+ */
71
112
loadMoreImages = ( ) => {
72
113
this . setState ( prev => ( {
73
114
currentPage : prev . currentPage + 1 ,
74
115
} ) ) ;
75
116
} ;
76
117
118
+ /**
119
+ * Handles form submission, updates the searchQuery, resets images, and sets currentPage to 1.
120
+ * @param {string } searchQuery - The new search query.
121
+ * @returns {void }
122
+ */
77
123
handleSubmit = searchQuery => {
78
124
if ( searchQuery === this . state . searchQuery ) {
79
125
return ;
@@ -86,36 +132,55 @@ class App extends Component {
86
132
} ) ;
87
133
} ;
88
134
135
+ /**
136
+ * Renders the main application component with various child components based on the state.
137
+ * @function
138
+ * @returns {JSX.Element } - The rendered React element.
139
+ */
89
140
render ( ) {
90
141
const { images, searchQuery, isLoading, error, totalHits } = this . state ;
91
142
92
143
return (
93
144
< >
145
+ { /* Search bar component */ }
94
146
< Searchbar onSubmit = { this . handleSubmit } />
147
+
148
+ { /* Main container for the application */ }
95
149
< Container className = "d-flex flex-column justify-content-center mb-5 mx-auto" >
96
- { isLoading && < Loader /> }
97
- { error && < ErrorAlert errorMessage = { error } /> }
150
+ { isLoading && < Loader /> } { ' ' }
151
+ { /* Loader component while images are being fetched */ }
152
+ { error && < ErrorAlert errorMessage = { error } /> } { ' ' }
153
+ { /* Error alert component */ }
98
154
{ images . length > 0 && ! error && (
99
155
< >
156
+ { /* Information about the search results */ }
100
157
< SearchResultInfo
101
158
searchQuery = { searchQuery }
102
159
totalHits = { totalHits }
103
160
/>
161
+
162
+ { /* Image gallery component */ }
104
163
< ImageGallery images = { images } />
164
+
165
+ { /* Load more button if there are more images to load */ }
105
166
{ totalHits > images . length && (
106
167
< LoadMoreBtn onClick = { this . loadMoreImages } />
107
168
) }
108
169
</ >
109
170
) }
171
+ { /* No results alert if no images are found */ }
110
172
{ ! error && searchQuery && totalHits === 0 && (
111
173
< NoResultsAlert searchQuery = { searchQuery } />
112
174
) }
113
-
175
+ { /* Welcome message for the image portal if no search query is present */ }
114
176
{ ! searchQuery && < ImagePortalWelcome /> }
115
177
</ Container >
116
178
</ >
117
179
) ;
118
180
}
119
181
}
120
182
183
+ /**
184
+ * Exporting the App component as the default export of the module.
185
+ */
121
186
export default App ;
0 commit comments