Skip to content

Commit 6deb578

Browse files
committed
v0.5 - fix minor bugs and update UI
1 parent 07e27f2 commit 6deb578

File tree

7 files changed

+79
-67
lines changed

7 files changed

+79
-67
lines changed

public/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
<meta property="og:title" content="Weather React" />
5757
<meta
5858
property="og:description"
59-
content="A robust weather application to provide current and 24 hour 7 day weather forecast for any city in the world. Weather forecast data is powered by Dark Sky and city search data is powered by Teleport."
59+
content="A robust weather application to provide current and 24 hour 7 day weather forecast for any city in the world built with ❤️ using React. Weather forecast data is powered by Dark Sky and city search data is powered by Teleport."
6060
/>
6161
<meta property="og:image" content="%PUBLIC_URL%/weather-react-app.png" />
6262

@@ -69,7 +69,7 @@
6969
<meta property="twitter:title" content="Weather React" />
7070
<meta
7171
property="twitter:description"
72-
content="A robust weather application to provide current and 24 hour 7 day weather forecast for any city in the world. Weather forecast data is powered by Dark Sky and city search data is powered by Teleport."
72+
content="A robust weather application to provide current and 24 hour 7 day weather forecast for any city in the world built with ❤️ using React. Weather forecast data is powered by Dark Sky and city search data is powered by Teleport."
7373
/>
7474
<meta
7575
property="twitter:image"

src/components/search/SearchComponent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ const SearchComponent = props => {
2626
backgroundColor: `${theme === 'dark' ? '#3a3a3a' : '#e2e8f0'}`,
2727
letterSpacing: '0.05em'
2828
}}
29-
className={`data-hj-whitelist block appearance-none w-full border-none rounded-full shadow py-3 pl-12 pr-4 mb-3 leading-tight focus:outline-none focus:bg-gray-200 truncate text-${colorTheme}`}
29+
className={`data-hj-whitelist block appearance-none w-full border-none rounded-full shadow py-3 pl-12 pr-6 mb-3 leading-tight focus:outline-none focus:bg-gray-200 truncate text-${colorTheme}`}
3030
id='grid-first-name'
3131
type='text'
3232
placeholder='Type city name to find weather forecast'
3333
onChange={props.citySearch}
3434
value={props.city}
3535
/>
36-
{props.showCaret && props.city.trim() ? (
36+
{props.showCaret ? (
3737
<div
3838
className='flex right-0 absolute top-0 mr-4 mt-3 cursor-pointer'
3939
onClick={props.caretClicked}>

src/components/weather/DayComponent.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,17 @@ const DayComponent = props => {
8080
index === selectedIndex ? 'flex' : 'flex'
8181
} flex-row justify-around sm:justify-center sm:flex sm:flex-col w-5/12 sm:w-full font-light mt-1`}>
8282
<div className='flex flex-row justify-center items-center mx-2 sm:my-1 text-xs sm:text-sm'>
83-
<p className='text-xl text-sun mr-2' title='sunrise'>
83+
<p
84+
className='text-xl lg:text-2xl text-sun mr-2 md:mr-3'
85+
title='sunrise'>
8486
<WeatherIconComponent type='sunrise' />
8587
</p>
8688
<p>{FormatTime(day.sunriseTime, day.timezone, 'h:mm')}</p>
8789
</div>
8890
<div className='flex flex-row justify-center items-center mx-2 sm:my-1 text-xs sm:text-sm'>
89-
<p className='text-xl text-sun mr-1' title='sunset'>
91+
<p
92+
className='text-xl lg:text-2xl text-sun mr-2 md:mr-1'
93+
title='sunset'>
9094
<WeatherIconComponent type='sunset' />
9195
</p>
9296
<p>{FormatTime(day.sunsetTime, day.timezone, 'HH:mm')}</p>

src/components/weather/InfoDetailComponent.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import WeatherIconComponent from './WeatherIconComponent'
1111

1212
const InfoDetailComponent = ({weatherCurrent}) => {
1313
const {weatherUnit, updateWeatherUnit} = useContext(WeatherUnitContext)
14-
14+
const weatherUnitTitle = weatherUnit === 'C' ? 'Celsius' : 'Fahrenheit'
15+
const unselectedWeatherUnit = weatherUnit === 'C' ? 'F' : 'C'
1516
const unitClick = unit => {
1617
// track event to GA
1718
Event({
@@ -78,22 +79,20 @@ const InfoDetailComponent = ({weatherCurrent}) => {
7879
<sup>o</sup>
7980
</p>
8081
<div className='-mt-10 mx-2 text-xl'>
82+
{/* selected weatherUnit */}
8183
<span
82-
className={`cursor-pointer ${
83-
weatherUnit === 'F' ? 'font-bold' : 'font-light opacity-75'
84-
}`}
85-
title='Fahrenheit'
86-
onClick={() => unitClick('F')}>
87-
F
84+
className='cursor-pointer font-bold'
85+
title={weatherUnitTitle}
86+
onClick={() => unitClick(weatherUnit)}>
87+
{weatherUnit}
8888
</span>
8989
<span className='mx-1 opacity-25'>|</span>
90+
{/* unselected weatherUnit */}
9091
<span
91-
className={`cursor-pointer ${
92-
weatherUnit === 'C' ? 'font-bold' : 'font-light opacity-75'
93-
}`}
94-
title='celsius'
95-
onClick={() => unitClick('C')}>
96-
C
92+
className='cursor-pointer font-light opacity-75'
93+
title={weatherUnitTitle}
94+
onClick={() => unitClick(unselectedWeatherUnit)}>
95+
{unselectedWeatherUnit}
9796
</span>
9897
</div>
9998
</div>
@@ -107,15 +106,17 @@ const InfoDetailComponent = ({weatherCurrent}) => {
107106
<div className='text-sm sm:text-lg ml-8'>
108107
<div className='flex flex-row sm:my-2'>
109108
<p className='font-light'>Humidity:</p>&nbsp;
110-
<p className='mx-1'>{Math.round(weatherCurrent.humidity)}</p>
109+
<p className='mx-1 font-bold'>
110+
{Math.round(weatherCurrent.humidity)}
111+
</p>
111112
<p className='text-sm mt-1'>
112113
<FiPercent />
113114
</p>
114115
</div>
115116
<div className='flex items-center sm:my-2'>
116117
<p>
117118
<span className='font-light'>Wind:</span>&nbsp;
118-
{computedSpeedValue()}{' '}
119+
<span className='font-bold'>{computedSpeedValue()} </span>
119120
</p>
120121
<p className='text-3xl'>
121122
{
@@ -127,7 +128,9 @@ const InfoDetailComponent = ({weatherCurrent}) => {
127128
</div>
128129
<p>
129130
<span className='font-light sm:my-2'>Feels like:</span>&nbsp;
130-
{computedTempValue('apparentTemperature')}
131+
<span className='font-bold'>
132+
{computedTempValue('apparentTemperature')}
133+
</span>
131134
<sup>o</sup>
132135
</p>
133136
</div>

src/containers/autocomplete/AutoCompleteContainer.js

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,47 +35,49 @@ class AutoCompleteContainer extends Component {
3535
debounceAddress = debounce(this.getAddresses, 1000)
3636

3737
searchCity = event => {
38-
this.setState({city: event.target.value})
39-
if (event.target.value.trim()) {
40-
this.setState({errorMessage: ''})
41-
this.debounceAddress()
42-
} else {
43-
this.clearState()
44-
}
38+
this.setState({city: event.target.value, errorMessage: ''})
39+
this.debounceAddress()
4540
}
4641

4742
// fetch valid matched addresses for searched city
4843
async getAddresses() {
49-
try {
50-
this.setState({showLoader: true})
51-
const {data} = await axios.get(
52-
`https://api.teleport.org/api/cities/?search=${this.state.city}`
53-
)
54-
55-
// populate addresses and show them if matching cities exist
56-
if (!isEmpty(data) && !isUndefined(data) && data.count > 0) {
57-
const results = data._embedded['city:search-results'].map(result => ({
58-
cityName: result.matching_full_name,
59-
cityId: result._links['city:item'].href.split('/')[5]
60-
}))
61-
// results is an array of `address` objects with cityName and cityId properties
62-
this.setState({
63-
addresses: results,
64-
showCaret: true,
65-
showAddresses: true,
66-
errorMessage: ''
67-
})
68-
} else {
69-
this.setState({showAddresses: false})
70-
this.handleError(
71-
'No matching cities found. Try searching with a valid city name!'
44+
// check for empty city value since deleting city value character by character will trigger the debounceAddress
45+
// city value could be empty when this function run
46+
// so this extra check will fix the bug of showing addresses list when there is no city name
47+
if (this.state.city.trim()) {
48+
try {
49+
this.setState({showLoader: true})
50+
const {data} = await axios.get(
51+
`https://api.teleport.org/api/cities/?search=${this.state.city}`
7252
)
53+
54+
// populate addresses and show them if matching cities exist
55+
if (!isEmpty(data) && !isUndefined(data) && data.count > 0) {
56+
const results = data._embedded['city:search-results'].map(result => ({
57+
cityName: result.matching_full_name,
58+
cityId: result._links['city:item'].href.split('/')[5]
59+
}))
60+
// results is an array of `address` objects with cityName and cityId properties
61+
this.setState({
62+
addresses: results,
63+
showCaret: true,
64+
showAddresses: true,
65+
errorMessage: ''
66+
})
67+
} else {
68+
this.setState({showAddresses: false})
69+
this.handleError(
70+
'No matching cities found. Try searching with a valid city name!'
71+
)
72+
}
73+
} catch (error) {
74+
this.handleError(error)
75+
Sentry.captureException(error)
76+
} finally {
77+
this.setState({showLoader: false})
7378
}
74-
} catch (error) {
75-
this.handleError(error)
76-
Sentry.captureException(error)
77-
} finally {
78-
this.setState({showLoader: false})
79+
} else {
80+
this.clearState()
7981
}
8082
}
8183

src/context/WeatherUnitContext.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useState, useEffect} from 'react'
22
const WeatherUnitContext = React.createContext({
3-
weatherUnit: 'F'
3+
weatherUnit: 'C'
44
})
55

66
const WeatherUnitContextProvider = ({children}) => {

src/index.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,22 @@ import * as Sentry from '@sentry/browser'
99
import LogRocket from 'logrocket'
1010
import setupLogRocketReact from 'logrocket-react'
1111

12-
const LOGROCKET_PROJECT_ID = process.env.REACT_APP_LOGROCKET_PROJECT_ID
13-
LogRocket.init(`${LOGROCKET_PROJECT_ID}`)
14-
setupLogRocketReact(LogRocket)
15-
1612
const SENTRY_DSN = process.env.REACT_APP_SENTRY_DSN
1713
Sentry.init({dsn: `${SENTRY_DSN}`})
1814

19-
// LogRocket and Sentry
20-
LogRocket.getSessionURL(sessionURL => {
21-
Sentry.configureScope(scope => {
22-
scope.setExtra('sessionURL', sessionURL)
15+
// track logrocket sessions only in the prod env
16+
if (process.env.NODE_ENV !== 'development') {
17+
const LOGROCKET_PROJECT_ID = process.env.REACT_APP_LOGROCKET_PROJECT_ID
18+
LogRocket.init(`${LOGROCKET_PROJECT_ID}`)
19+
setupLogRocketReact(LogRocket)
20+
21+
// LogRocket and Sentry
22+
LogRocket.getSessionURL(sessionURL => {
23+
Sentry.configureScope(scope => {
24+
scope.setExtra('sessionURL', sessionURL)
25+
})
2326
})
24-
})
27+
}
2528

2629
const app = (
2730
<Router basename={process.env.PUBLIC_URL}>

0 commit comments

Comments
 (0)