1
- import React from "react" ;
2
- import "./App.scss" ;
3
-
4
-
5
- import CitiesGrid from "./components/cities-grid" ;
6
-
7
1
/**
8
- * # Desafio front-end
9
- *
10
- * É um componente que terá um select e um botão, e terá
11
- * uma listagem ou grid com dados logo abaixo.
12
- *
13
- * O componente deve ser montado inicialmente com um
14
- * placeholder.
15
- *
16
- * Deve então fazer um fetch na API para buscar a lista
17
- * de todos os estados do Brasil.
18
- *
19
- * Depois, listar no elemento do tipo select todos estes
20
- * países como opções.
21
- *
22
- * Quando o usuário selecionar um estado, o botão fica ativo.
23
- *
24
- * Se o usuário clicar no botão, deve então buscar a lista
25
- * de cidades naquele estado.
26
- *
27
- * Quando obtiver o resultado, deve listar as cidades daquele
28
- * estado exibindo o nome da cidade, e o nome da microrregião
29
- * daquela cidade.
30
- *
31
- * # Bonus points
32
- * - Colocar tanto os estados quanto as cidades em ordem
33
- * alfabética
34
- * - Se o dispositivo for pequeno (mobile), este grid pode
35
- * mostrar apenas o nome da cidade.
36
- *
2
+ * Busca a lista de estados no Brasil.
3
+ * Ao clicar no botão, se um estado estiver selecionado, lista as cidades
4
+ * daquele estado.
5
+ *
37
6
* # Helpers
38
7
* API para pegar a lista de estados do Brasil:
39
8
* https://servicodados.ibge.gov.br/api/v1/localidades/estados?orderBy=nome
@@ -42,27 +11,45 @@ import CitiesGrid from "./components/cities-grid";
42
11
* https://servicodados.ibge.gov.br/api/v1/localidades/estados/${UF}/distritos
43
12
*
44
13
*/
14
+ import React from "react" ;
15
+ import CitiesGrid from "./components/cities-grid" ;
16
+
17
+ import "./App.scss" ;
45
18
19
+ /**
20
+ * Generates the url used to retrieve the list of cities for a given state.
21
+ *
22
+ * @param {String } UF The acronym for the state
23
+ * @returns String The parsed URL for the API to return the list of cities within that state
24
+ */
46
25
const getCitiesAPI_URL = function ( UF = "" ) {
47
26
UF = UF . substring ( 0 , 2 ) ;
48
27
return `https://servicodados.ibge.gov.br/api/v1/localidades/estados/${ UF } /distritos` ;
49
28
} ;
50
29
30
+ // The url for the API to retrieve the list of states.
51
31
const API_STATES_UF = `https://servicodados.ibge.gov.br/api/v1/localidades/estados?orderBy=nome` ;
52
32
33
+ /**
34
+ * This object contains the list of cities already downloaded
35
+ * for the states.
36
+ * Each state is a `key` in the object.
37
+ */
53
38
const CACHED_CITIES = { } ;
54
39
40
+ /**
41
+ * Our main App entrypoint.
42
+ *
43
+ * @returns ReactComponent
44
+ */
55
45
export default function App ( ) {
56
- const [ statesList , setStatesList ] = React . useState ( null ) ;
57
-
58
46
47
+ const [ statesList , setStatesList ] = React . useState ( null ) ;
59
48
const [ loadingCities , setLoadingCities ] = React . useState ( null ) ;
60
-
61
-
62
49
const [ selectedState , setSelectedState ] = React . useState ( null ) ;
63
50
const [ citiesForState , setCitiesForCurrentUF ] = React . useState ( null ) ;
64
51
65
-
52
+ // will load the list of states as soon as the component is ready (mount)
66
53
React . useEffect ( ( _ ) => {
67
54
fetch ( API_STATES_UF )
68
55
. then ( async ( response ) => {
@@ -76,17 +63,14 @@ export default function App() {
76
63
} , [ ] ) ;
77
64
78
65
/**
79
- * in the first render , we show only the placeholder
66
+ * If the list of states is not yet available , we show only a placeholder
80
67
*/
81
68
if ( ! statesList ) {
82
69
return < div className = "no-data" > Building up...</ div > ;
83
70
}
84
71
85
72
/**
86
73
* Sorts a list based on item's names.
87
- *
88
- * As both states and cities coming from the api have a
89
- * name, we can use the same function to sort them both.
90
74
*/
91
75
function sortByName ( a , b ) {
92
76
return a . nome . localeCompare ( b . nome ) ;
@@ -98,8 +82,6 @@ export default function App() {
98
82
*
99
83
* @param {Event } event The onChange event
100
84
*/
101
-
102
-
103
85
function onStateChange ( event ) {
104
86
setCitiesForCurrentUF ( null ) ;
105
87
setSelectedState ( event . target . value ) ;
@@ -115,7 +97,9 @@ export default function App() {
115
97
return setCitiesForCurrentUF ( CACHED_CITIES [ selectedState ] ) ;
116
98
}
117
99
100
+ // mark it as in the "loading" state
118
101
setLoadingCities ( true ) ;
102
+
119
103
fetch ( getCitiesAPI_URL ( selectedState ) )
120
104
. then ( async ( response ) => {
121
105
const data = await response . json ( ) ;
@@ -148,8 +132,6 @@ export default function App() {
148
132
Ok
149
133
</ button >
150
134
</ div >
151
- { /* <div className="main">{getCitiesGrid()}</div> */ }
152
-
153
135
154
136
< div className = "main" >
155
137
< CitiesGrid
@@ -158,6 +140,7 @@ export default function App() {
158
140
cities = { citiesForState }
159
141
/>
160
142
</ div >
143
+
161
144
</ div >
162
145
) ;
163
146
}
0 commit comments