Skip to content
This repository has been archived by the owner on Nov 11, 2022. It is now read-only.

Commit

Permalink
v3.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurenceHo committed Jan 26, 2021
1 parent d4c4f41 commit 4f274cb
Show file tree
Hide file tree
Showing 29 changed files with 774 additions and 303 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea/*
*.iml
node_modules/*
dist/*
functions/node_modules/*
Expand Down
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ cloud function serverless platform with React frontend app.
1. The latest version of Nodejs and npm need to be installed.
2. Google API Key
3. Dark Sky weather API key
4. Windy API key

## Getting Started
* Clone the repo: `git clone https://github.com/LaurenceHo/reactjs-beautiful-weather.git`
* Install npm package: `npm install`
* Put your google & [dark sky API key](https://darksky.net/dev) into `./functions/apiKey.js`
* Put your google & [dark sky API key](https://darksky.net/dev) into [`./functions/apiKey.js`](./functions/apikey.js)
* Put your [Windy API key](https://api4.windy.com/) into [`./src/pages/weather-map.tsx`](./src/pages/weather-map.tsx)
* Bundle frontend code: `npm run build`
* If you want to start client using webpack dev server: `npm run start`, and visit in your browser: `http://localhost:8080`.

Expand Down Expand Up @@ -414,6 +416,53 @@ import 'echarts/lib/component/toolbox';
* Don't use @types/antd, as antd provides a built-in ts definition already. Also only use TypeScript 2.9.2 this moment,
because ant design doesn't support TypeScript 3+.

## Windy API
Since I put the protection for my Windy API, only the allowed domain name can use this API key. Windy API is free,
please feel free to apply for a new one for yourself.

### Usage
There is no npm package for installing Windy API so we have to import source in [index.html](./src/index.html)
```
<head>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://api4.windy.com/assets/libBoot.js"></script>
</head>
```
Windy API v4 was based on Leaflet 1.4, so import leaflet by this way is very important.
How to make these 2 JavaScript 3rd party libraries working in TypeScript? We need to declare the definition in [TypeScript
Declaration File](./src/typings.d.ts).
```
declare var windyInit: any;
declare var L: any;
```
After that, we can use `windyInit` and `L` these 2 parameters directly without importing module into TypeScript file.
In [`weather-map.tsx`](./src/pages/weather-map.tsx), when we init Windy API, the basic usage it's very simple:
```
const options = {
// Required: API key
key: 'PsLAtXpsPTZexBwUkO7Mx5I',
// Put additional console output
verbose: true,
// Optional: Initial state of the map
lat: 50.4,
lon: 14.3,
zoom: 5,
}
windyInit(options, (windyAPI: any) => {
const { map } = windyAPI;
L.popup()
.setLatLng([50.4, 14.3])
.setContent("Hello World")
.openOn( map );
});
render() {
return (<div id='windy' />);
}
```

## Live demo
[https://react-beautiful-weather-app.firebaseapp.com/](https://react-beautiful-weather-app.firebaseapp.com/)

Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-weather-app",
"version": "1.2.0",
"version": "3.3.1",
"description": "react-weather-app",
"main": "index.js",
"scripts": {
Expand All @@ -10,7 +10,7 @@
"firebase-init": "firebase login && firebase init",
"firebase-add": "firebase use --add",
"deploy-functions": "firebase deploy --only functions",
"lint": "eslint --ext .ts,.tsx src sample --fix"
"lint": "eslint --ext .ts,.tsx src --fix"
},
"author": "Laurence Ho",
"license": "MIT",
Expand All @@ -20,7 +20,8 @@
"Webpack",
"Typescript",
"D3",
"antd"
"antd",
"ECharts"
],
"husky": {
"hooks": {
Expand All @@ -43,6 +44,7 @@
"dependencies": {
"antd": "^3.16.6",
"axios": "^0.18.0",
"connected-react-router": "^6.4.0",
"d3": "^5.9.2",
"echarts": "^4.2.1",
"lodash": "^4.17.11",
Expand Down Expand Up @@ -78,7 +80,6 @@
"lint-staged": "^8.1.6",
"mini-css-extract-plugin": "^0.6.0",
"prettier": "^1.17.0",
"redux-devtools-extension": "^2.13.8",
"source-map-loader": "^0.2.4",
"terser-webpack-plugin": "^1.2.3",
"ts-loader": "^5.4.5",
Expand Down
14 changes: 11 additions & 3 deletions src/components/chart-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Utils } from '../utils';
import { Timezone } from './data-model';

export const chartConfig: any = (units: string, timezone: Timezone, hourly: any) => {
const fontSize = 14;

const formatterXAxisLabel = (value: number, index: number) => {
if (index === 0) {
return 'Now';
Expand All @@ -21,13 +23,13 @@ export const chartConfig: any = (units: string, timezone: Timezone, hourly: any)
const time = Utils.getLocalTime(temperature.name, timezone.offset, 'YYYY-MM-DD HH:mm');

return `
<div style="font-size:0.9rem; color:#949494; line-height:1.1rem;">${time}</div>
<div class="weather-chart-tooltip-time">${time}</div>
</br>
<div style="color:#2E2E2E; font-size:0.8rem; font-weight:500; line-height: 0.3rem;">
<div class="weather-chart-tooltip-item">
Temperature:${Utils.getTemperature(temperature.value, units)}
</div>
</br>
<div style="color:#2E2E2E; font-size:0.8rem; font-weight:500; line-height: 0.3rem;">
<div class="weather-chart-tooltip-item">
Rain: ${rain.value} ${units === 'us' ? 'in' : 'mm'}
</div>
`;
Expand All @@ -50,12 +52,16 @@ export const chartConfig: any = (units: string, timezone: Timezone, hourly: any)
legend: {
data: ['Temperature', 'Rain'],
right: '10%',
textStyle: {
fontSize,
},
},
xAxis: {
type: 'category',
data: map(hourly.data, 'time').slice(0, 23),
axisLabel: {
formatter: formatterXAxisLabel,
fontSize,
},
},
yAxis: [
Expand All @@ -64,6 +70,7 @@ export const chartConfig: any = (units: string, timezone: Timezone, hourly: any)
max: temperatureMax,
axisLabel: {
formatter: units === 'us' ? '{value} ℉' : '{value} ℃',
fontSize,
},
splitLine: {
show: false,
Expand All @@ -81,6 +88,7 @@ export const chartConfig: any = (units: string, timezone: Timezone, hourly: any)
max: rainMax,
axisLabel: {
formatter: units === 'us' ? '{value} in' : '{value} mm',
fontSize,
},
},
],
Expand Down
62 changes: 35 additions & 27 deletions src/components/current-weather.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Col from 'antd/lib/col';
import Row from 'antd/lib/row';
import * as React from 'react';
import { connect } from 'react-redux';

import { Utils } from '../utils';
import { WeatherIcon } from './icon/weather-icon';
import { WindIcon } from './icon/wind-icon';
Expand All @@ -13,42 +14,49 @@ export class CurrentWeather extends React.Component<any, any> {
return (
<div>
<Row type='flex' justify='center' className='current-weather-top'>
<Col xs={4} sm={4} md={4} lg={3} xl={3}>
<span>
<Col xs={8} sm={6} md={6} lg={4}>
<div className='current-weather-top-item'>
Rain: {Utils.getRain(weather.precipIntensity, weather.precipProbability, filter.units)}
<i className='wi wi-humidity' />
</span>
</div>
</Col>
<Col xs={3} sm={3} md={3} lg={2} xl={2}>
Wind: {Utils.getWindSpeed(weather.windSpeed, filter.units)} <WindIcon degree={weather.windBearing} />
<Col xs={8} sm={6} md={6} lg={3}>
<div className='current-weather-top-item'>
Wind: {Utils.getWindSpeed(weather.windSpeed, filter.units)} <WindIcon degree={weather.windBearing} />
</div>
</Col>
<Col xs={3} sm={3} md={3} lg={2} xl={2}>
<span>
<Col xs={8} sm={6} md={6} lg={3}>
<div className='current-weather-top-item'>
Humidity: {Math.round(weather.humidity * 100)} <i className='wi wi-humidity' />
</span>
</div>
</Col>
<Col xs={4} sm={4} md={4} lg={3} xl={3}>
Pressure: {Utils.getPressure(weather.pressure, filter.units)}
<Col xs={8} sm={6} md={6} lg={4}>
<div className='current-weather-top-item'>
Pressure: {Utils.getPressure(weather.pressure, filter.units)}
</div>
</Col>
<Col xs={3} sm={3} md={3} lg={2} xl={2}>
Dew Point: {Utils.getTemperature(weather.dewPoint, filter.units)}
<Col xs={8} sm={8} md={8} lg={3}>
<div className='current-weather-top-item'>
Dew Point: {Utils.getTemperature(weather.dewPoint, filter.units)}
</div>
</Col>
<Col xs={3} sm={3} md={3} lg={2} xl={2}>
UV Index: {weather.uvIndex}
<Col xs={8} sm={8} md={8} lg={3}>
<div className='current-weather-top-item'>UV Index: {weather.uvIndex}</div>
</Col>
<Col xs={3} sm={3} md={3} lg={2} xl={2}>
Visibility: {Utils.getDistance(weather.visibility, filter.units)}
<Col xs={6} sm={8} md={8} lg={3}>
<div className='current-weather-top-item'>
Visibility: {Utils.getDistance(weather.visibility, filter.units)}
</div>
</Col>
</Row>
<Row type='flex' justify='center' className='current-weather-location'>
{location}
</Row>
<Row type='flex' justify='center'>
<Col xs={2} sm={2} md={2} lg={2} xl={2} xxl={1}>
<Col xs={4} sm={3} md={2} lg={2} xl={1} className='current-weather-icon'>
<WeatherIcon icon={weather.icon} size='4rem' />
</Col>
<Col span={3}>
<div style={{ paddingTop: '1rem' }}>
<Col xs={12} sm={8} md={6} lg={4} xl={4}>
<div className='current-weather-summary'>
<div>{Utils.getLocalTime(weather.time, timezone.offset, 'YYYY-MM-DD HH:mm')}</div>
<div>
{weather.summary} {Utils.getTemperature(weather.temperature, filter.units)}
Expand All @@ -64,13 +72,13 @@ export class CurrentWeather extends React.Component<any, any> {

const mapStateToProps = (state: any) => {
return {
filter: state.filter,
location: state.location,
weather: state.weather,
forecast: state.forecast,
timezone: state.timezone,
isLoading: state.isLoading,
error: state.error,
filter: state.weather.filter,
location: state.weather.location,
weather: state.weather.weather,
forecast: state.weather.forecast,
timezone: state.weather.timezone,
isLoading: state.weather.isLoading,
error: state.weather.error,
};
};

Expand Down
89 changes: 0 additions & 89 deletions src/components/d3-demo/d3-force.css

This file was deleted.

Loading

0 comments on commit 4f274cb

Please sign in to comment.