Skip to content

Commit

Permalink
Merge pull request #316 from NASA-IMPACT/develop
Browse files Browse the repository at this point in the history
Release 1.0.0
  • Loading branch information
olafveerman authored Jun 25, 2020
2 parents a494f00 + bf781cc commit 5ee3ca6
Show file tree
Hide file tree
Showing 29 changed files with 476 additions and 203 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Covid Dashboard
# COVID-19 Dashboard
As communities around the world have changed their behavior in response to the spread of COVID-19, NASA satellites have observed changes in the environment. This experimental dashboard reflects a rapid response to COVID-19 that is currently underway and will continue to evolve as more data becomes available.

Visit the live site on: https://earthdata.nasa.gov/covid19/

This dashboard is powered by an [open source API](https://github.com/NASA-IMPACT/covid-api/) that is developed in parallel. This API focuses on serving the Cloud Optimized GeoTIFF and time-series indicator data that people can interact with in the dashboard.

![](https://user-images.githubusercontent.com/751330/85645349-7213ac00-b667-11ea-9ab0-52e2b16d416d.jpg)

## Installation and Usage
The steps below will walk you through setting up your own instance of the project.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed app/assets/graphics/content/la-port.png
Binary file not shown.
5 changes: 5 additions & 0 deletions app/assets/icons/collecticons/calendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions app/assets/scripts/components/about/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ export default class About extends React.Component {
our yards more abundant.
</p>
<p>
NASA’s continuous and sometimes near-real-time measurements of Earth allow for understanding both the systems
The National Aeronautics and Space Administration&apos;s (NASA) continuous and sometimes near-real-time measurements of Earth allow for understanding both the systems
changes themselves and the potential impact on economies and society during the pandemic – and as the world
slowly returns to operations.
</p>
<p>
This dashboard features data collected and analyzed by the National Aeronautics and Space Administration (NASA).
This dashboard features data collected and analyzed by NASA.
Information about Earth systems is gathered by a fleet of powerful global Earth-Observing satellites, instruments
aboard the International Space Station, from airborne science campaigns, and via ground observations. With this
data we have been able to monitor some of those changes andand this is allowing us to track and compare these
data we have been able to monitor some of those changes and this is allowing us to track and compare these
changes over time.
</p>
<p>
Expand Down
141 changes: 116 additions & 25 deletions app/assets/scripts/components/common/date-picker.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import { PropTypes as T } from 'prop-types';
import styled from 'styled-components';
import { format } from 'date-fns';
import { format, isSameYear, isSameMonth } from 'date-fns';

import Dropdown from './dropdown';
import Button from '../../styles/button/button';
import DateRange from './date-range';
import { FormHelper, FormHelperMessage } from '../../styles/form/helper';
import { glsp } from '../../styles/utils/theme-values';

const DATE_FORMAT = 'MMM dd, yyyy';

Expand All @@ -24,6 +26,25 @@ const DropdownDatePicker = styled(Dropdown)`
}
`;

const DateRangeSelector = styled(DateRange)`
display: flex;
flex-flow: column;
align-items: center;
`;

const PickerFooter = styled.div`
display: flex;
& > * {
margin-right: ${glsp()};
}
`;

const FormHelperPicker = styled(FormHelper)`
margin-top: ${glsp()};
max-width: 17rem;
`;

class DatePicker extends React.Component {
constructor (props) {
super(props);
Expand All @@ -44,88 +65,158 @@ class DatePicker extends React.Component {
// Committed props are tracked with a double leading underscore.
// See getDerivedStateFromProps below.
// https://reactjs.org/blog/2018/05/23/react-v-16-4.html#bugfix-for-getderivedstatefromprops
__date: props.dateState,
date: props.dateState
__range: props.dateState,
range: props.dateState
};

this.onClearClick = this.onClearClick.bind(this);
this.onApplyClick = this.onApplyClick.bind(this);
this.onDateChange = this.onDateChange.bind(this);

this.dropdownRef = React.createRef();
}

static getDerivedStateFromProps (props, state) {
if (props.dateState !== state.__date) {
if (props.dateState !== state.__range) {
return {
__date: props.dateState,
date: props.dateState
__range: props.dateState,
range: props.dateState
};
}
return null;
}

onClearClick () {
this.setState({ range: { start: null, end: null } });
}

onDropdownClose () {
// There must always be a date set.
// If the date was cleared, reset to original.
if (!this.state.date) {
if (!this.state.range.start && !this.state.range.end) {
this.setState(state => ({
date: state.__date
range: state.__range
}));
}
}

onDateChange (date) {
this.setState({ date: date.start }, () => {
this.props.onChange(this.state.date);
onApplyClick () {
// If applying only with start, consider that date start and end.
this.setState(state => {
const {
range: { start, end }
} = state;

if (!end) {
return {
range: { start, end: start }
};
}
}, () => {
this.props.onChange(this.state.range);
this.dropdownRef.current.close();
});
}

onDateChange (range) {
this.setState({ range });
}

getTriggerLabel () {
const { dateState } = this.props;
return dateState ? format(dateState, DATE_FORMAT) : 'Select date';
const {
dateState: { start, end }
} = this.props;

if (start) {
const startStr = format(start, DATE_FORMAT);
if (!end) {
return `${startStr} — end`;
}

const endStr = format(end, DATE_FORMAT);
if (startStr === endStr) {
return startStr;
}

if (isSameMonth(start, end) && isSameYear(start, end)) {
return `${format(start, 'MMM dd')}-${format(end, 'dd, yyyy')}`;
} else if (isSameYear(start, end)) {
return `${format(start, 'MMM dd')}${endStr}`;
} else {
return `${startStr}${endStr}`;
}
}

return 'From start — end';
}

render () {
const { id, label, dateDomain } = this.props;
const { date } = this.state;
const { id, label, dateDomain, validate } = this.props;
const { range } = this.state;

const dateRangeVal = {
start: date,
end: date
};
const validationError = validate(range);
const isValidRange = !validationError;

return (
<DropdownDatePicker
ref={this.dropdownRef}
onChange={(open) => !open && this.onDropdownClose()}
alignment='right'
direction='up'
direction='down'
triggerElement={
<Button variation='base-plain' size='small' title='Select a date'>
<Button
variation='base-achromic'
size='small'
title='Select a date range'
hideText
useIcon='calendar'
>
{this.getTriggerLabel()}
</Button>
}
>
<DateRange
<DateRangeSelector
id={id}
label={label}
value={dateRangeVal}
value={range}
min={dateDomain[0]}
max={dateDomain[1]}
allowRange
onChange={this.onDateChange}
onPickerChange={() => this.dropdownRef.current.reposition()}
/>
<PickerFooter>
<Button variation='base-plain' onClick={this.onClearClick}>
Clear
</Button>
<Button
disabled={!range.start || !isValidRange}
variation='primary-raised-dark'
onClick={this.onApplyClick}
>
Apply
</Button>
</PickerFooter>
{!isValidRange && (
<FormHelperPicker>
<FormHelperMessage invalid>{validationError}</FormHelperMessage>
</FormHelperPicker>
)}
</DropdownDatePicker>
);
}
}

DatePicker.propTypes = {
dateState: T.object,
dateState: T.shape({
start: T.object,
end: T.object
}),
dateDomain: T.array,
id: T.string,
label: T.string,
onChange: T.func
onChange: T.func,
validate: T.func
};

export default DatePicker;
10 changes: 6 additions & 4 deletions app/assets/scripts/components/common/date-range.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class DateRange extends React.Component {
allowRange
} = this.props;

if (allowRange) {
if (!allowRange) {
return onChange({
start: date,
end: date
Expand Down Expand Up @@ -97,7 +97,8 @@ class DateRange extends React.Component {
value: { start, end },
min,
max,
allowRange
allowRange,
className
} = this.props;

const compProps = allowRange ? {
Expand All @@ -111,15 +112,15 @@ class DateRange extends React.Component {
};

return (
<div onClick={this.onPickerClick}>
<div className={className} onClick={this.onPickerClick}>
{this.state.pickerType === 'day' ? (
<DatePicker
previousMonthButtonLabel={<span>Previous Month</span>}
nextMonthButtonLabel={<span>Next Month</span>}
onChange={this.onDateSelect}
// selectsStart={!start || !end}
// selectsEnd={!start || !end}
monthsShown={2}
monthsShown={1}
shouldCloseOnSelect={false}
// startDate={start}
// endDate={end || start}
Expand Down Expand Up @@ -148,6 +149,7 @@ class DateRange extends React.Component {
}

DateRange.propTypes = {
className: T.string,
value: T.shape({
start: T.object,
end: T.object
Expand Down
54 changes: 32 additions & 22 deletions app/assets/scripts/components/common/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,14 @@ const DropContent = styled.div`
.tether-target-attached-top.tether-element-attached-bottom & {
${transitions.up.end}
&.drop-trans-appear,
&.drop-trans-enter {
${transitions.up.start}
}
&.drop-trans-appear-active,
&.drop-trans-enter-active {
${transitions.up.end}
}
&.drop-trans-exit {
${transitions.up.end}
}
Expand All @@ -393,7 +400,14 @@ const DropContent = styled.div`
.tether-target-attached-bottom.tether-element-attached-top & {
${transitions.down.end}
&.drop-trans-appear,
&.drop-trans-enter {
${transitions.down.start}
}
&.drop-trans-appear-active,
&.drop-trans-enter-active {
${transitions.down.end}
}
&.drop-trans-exit {
${transitions.down.end}
}
Expand All @@ -405,7 +419,14 @@ const DropContent = styled.div`
.tether-target-attached-right.tether-element-attached-left & {
${transitions.right.end}
&.drop-trans-appear,
&.drop-trans-enter {
${transitions.right.start}
}
&.drop-trans-appear-active,
&.drop-trans-enter-active {
${transitions.right.end}
}
&.drop-trans-exit {
${transitions.right.end}
}
Expand All @@ -417,7 +438,14 @@ const DropContent = styled.div`
.tether-target-attached-left.tether-element-attached-right & {
${transitions.left.end}
&.drop-trans-appear,
&.drop-trans-enter {
${transitions.left.start}
}
&.drop-trans-appear-active,
&.drop-trans-enter-active {
${transitions.left.end}
}
&.drop-trans-exit {
${transitions.left.end}
}
Expand All @@ -426,24 +454,6 @@ const DropContent = styled.div`
${transitions.left.start}
}
}
&&.drop-trans-appear,
&&.drop-trans-enter {
${({ direction }) => transitions[direction].start}
}
&&.drop-trans-enter-active,
&&.drop-trans-appear-active {
${({ direction }) => transitions[direction].end}
}
&&.drop-trans-exit {
${({ direction }) => transitions[direction].end}
}
&&.drop-trans-exit-active {
${({ direction }) => transitions[direction].start}
}
`;

class TransitionItem extends React.Component {
Expand Down
Loading

0 comments on commit 5ee3ca6

Please sign in to comment.