1
1
import React , { useCallback , useState } from 'react' ;
2
2
import { useHistory , useLocation } from 'react-router-dom' ;
3
+ import styled from 'styled-components' ;
3
4
4
5
import { fetchShortestPaths } from '../api.ts' ;
5
6
import { WikipediaPage , WikipediaPageId } from '../types.ts' ;
6
7
import { getRandomPageTitle } from '../utils.ts' ;
8
+ import { Button } from './common/Button.tsx' ;
7
9
import { Logo } from './common/Logo.tsx' ;
8
- import { ErrorMessage } from './ErrorMessage.tsx' ;
9
10
import { InputFlexContainer , Modal , P } from './Home.styles.ts' ;
10
11
import { Loading } from './Loading.tsx' ;
11
12
import { NavLinks } from './NavLinks.tsx' ;
12
13
import { PageInput } from './PageInput.tsx' ;
13
14
import { Results } from './Results.tsx' ;
14
- import { SearchButton } from './SearchButton.tsx' ;
15
15
import { SwapInputValuesButton } from './SwapInputValuesButton.tsx' ;
16
16
17
17
interface ShortestPathsState {
@@ -24,6 +24,50 @@ interface ShortestPathsState {
24
24
readonly durationInSeconds : string ;
25
25
}
26
26
27
+ const SearchButtonWrapper = styled ( Button ) `
28
+ width: 240px;
29
+ height: 72px;
30
+ margin: 0 auto 40px;
31
+ font-size: 32px;
32
+ border-radius: 8px;
33
+
34
+ @media (max-width: 600px) {
35
+ width: 200px;
36
+ height: 60px;
37
+ font-size: 28px;
38
+ }
39
+ ` ;
40
+
41
+ const ErrorMessageWrapper = styled . p `
42
+ width: 700px;
43
+ margin: 40px auto;
44
+ font-size: 28px;
45
+ text-align: center;
46
+ line-height: 1.5;
47
+ color: ${ ( { theme} ) => theme . colors . red } ;
48
+ text-shadow: black 1px 1px;
49
+
50
+ @media (max-width: 1200px) {
51
+ width: 70%;
52
+ font-size: 24px;
53
+ }
54
+ ` ;
55
+
56
+ const ErrorMessage : React . FC < {
57
+ readonly text : string ;
58
+ } > = ( { text} ) => {
59
+ const tokens = text . split ( '"' ) ;
60
+
61
+ return (
62
+ < ErrorMessageWrapper >
63
+ { tokens . map ( ( token , i ) =>
64
+ // Bold page titles in the provided error message.
65
+ i % 2 === 0 ? < span key = { i } > { token } </ span > : < b key = { i } > "{ token } "</ b >
66
+ ) }
67
+ </ ErrorMessageWrapper >
68
+ ) ;
69
+ } ;
70
+
27
71
export const Home : React . FC = ( ) => {
28
72
const history = useHistory ( ) ;
29
73
const location = useLocation ( ) ;
@@ -39,7 +83,7 @@ export const Home: React.FC = () => {
39
83
const [ targetPagePlaceholderText , setTargetPagePlaceholderText ] = useState ( getRandomPageTitle ( ) ) ;
40
84
41
85
const [ shortestPathsState , setShortestPathsState ] = useState < ShortestPathsState | null > ( null ) ;
42
- const [ isFetchingShortestPaths , setIsFetchingShortestPaths ] = useState ( false ) ;
86
+ const [ isFetchingResults , setIsFetchingResults ] = useState ( false ) ;
43
87
const [ errorMessage , setErrorMessage ] = useState < string | null > ( null ) ;
44
88
45
89
const handleOpenModal = ( ) => setShowModal ( true ) ;
@@ -49,7 +93,7 @@ export const Home: React.FC = () => {
49
93
const startTimeInMilliseconds = Date . now ( ) ;
50
94
51
95
setShortestPathsState ( null ) ;
52
- setIsFetchingShortestPaths ( true ) ;
96
+ setIsFetchingResults ( true ) ;
53
97
setErrorMessage ( null ) ;
54
98
55
99
const actualSourcePageTitle = sourcePageTitle || sourcePagePlaceholderText ;
@@ -96,7 +140,7 @@ export const Home: React.FC = () => {
96
140
}
97
141
}
98
142
99
- setIsFetchingShortestPaths ( false ) ;
143
+ setIsFetchingResults ( false ) ;
100
144
} , [
101
145
history ,
102
146
sourcePagePlaceholderText ,
@@ -115,7 +159,7 @@ export const Home: React.FC = () => {
115
159
116
160
// Reset shortest paths reponse data.
117
161
setShortestPathsState ( null ) ;
118
- setIsFetchingShortestPaths ( false ) ;
162
+ setIsFetchingResults ( false ) ;
119
163
setErrorMessage ( null ) ;
120
164
} }
121
165
/>
@@ -168,25 +212,26 @@ export const Home: React.FC = () => {
168
212
/>
169
213
</ InputFlexContainer >
170
214
171
- < SearchButton
172
- sourcePageTitle = { sourcePageTitle }
173
- targetPageTitle = { targetPageTitle }
174
- isFetchingResults = { isFetchingShortestPaths }
175
- onClick = { async ( ) => {
176
- if ( sourcePageTitle . trim ( ) . length === 0 ) {
177
- setSourcePageTitle ( sourcePagePlaceholderText ) ;
178
- }
179
- if ( targetPageTitle . trim ( ) . length === 0 ) {
180
- setTargetPageTitle ( targetPagePlaceholderText ) ;
181
- }
182
-
183
- await handleFetchShortestPaths ( ) ;
184
- } }
185
- />
215
+ { isFetchingResults ? (
216
+ < SearchButtonWrapper
217
+ onClick = { async ( ) => {
218
+ if ( sourcePageTitle . trim ( ) . length === 0 ) {
219
+ setSourcePageTitle ( sourcePagePlaceholderText ) ;
220
+ }
221
+ if ( targetPageTitle . trim ( ) . length === 0 ) {
222
+ setTargetPageTitle ( targetPagePlaceholderText ) ;
223
+ }
224
+
225
+ await handleFetchShortestPaths ( ) ;
226
+ } }
227
+ >
228
+ Go!
229
+ </ SearchButtonWrapper >
230
+ ) : null }
186
231
187
232
{ errorMessage !== null ? (
188
233
< ErrorMessage text = { errorMessage } />
189
- ) : isFetchingShortestPaths ? (
234
+ ) : isFetchingResults ? (
190
235
< Loading />
191
236
) : shortestPathsState ? (
192
237
< Results
0 commit comments