diff --git a/package-lock.json b/package-lock.json index fb298522..9683a5a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4691,6 +4691,18 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, + "history": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz", + "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==", + "requires": { + "invariant": "^2.2.1", + "loose-envify": "^1.2.0", + "resolve-pathname": "^2.2.0", + "value-equal": "^0.4.0", + "warning": "^3.0.0" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -8408,6 +8420,53 @@ "warning": "^3.0.0" } }, + "react-router": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", + "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", + "requires": { + "history": "^4.7.2", + "hoist-non-react-statics": "^2.5.0", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.1", + "warning": "^4.0.1" + }, + "dependencies": { + "warning": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.1.tgz", + "integrity": "sha512-rAVtTNZw+cQPjvGp1ox0XC5Q2IBFyqoqh+QII4J/oguyu83Bax1apbo2eqB8bHRS+fqYUBagys6lqUoVwKSmXQ==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-router-dom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz", + "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==", + "requires": { + "history": "^4.7.2", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.1", + "react-router": "^4.3.1", + "warning": "^4.0.1" + }, + "dependencies": { + "warning": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.1.tgz", + "integrity": "sha512-rAVtTNZw+cQPjvGp1ox0XC5Q2IBFyqoqh+QII4J/oguyu83Bax1apbo2eqB8bHRS+fqYUBagys6lqUoVwKSmXQ==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, "react-scripts": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-1.1.4.tgz", @@ -9371,6 +9430,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" }, + "resolve-pathname": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz", + "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -10672,6 +10736,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", + "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index b9db23a7..b103db39 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "react": "^16.4.0", "react-dom": "^16.4.0", "react-google-maps": "^9.4.5", + "react-router-dom": "^4.3.1", "react-scripts": "1.1.4", "react-time": "^4.3.0", "request": "^2.87.0", diff --git a/src/components/AboutUs/AboutUs.css b/src/components/AboutUs/AboutUs.css new file mode 100644 index 00000000..fee47ead --- /dev/null +++ b/src/components/AboutUs/AboutUs.css @@ -0,0 +1,7 @@ +div.aboutUs{ + height: 100vh; +} + +div.aboutUs p{ + text-align: center; +} diff --git a/src/components/AboutUs/AboutUs.js b/src/components/AboutUs/AboutUs.js new file mode 100644 index 00000000..e0e452d0 --- /dev/null +++ b/src/components/AboutUs/AboutUs.js @@ -0,0 +1,22 @@ +import React, { Component } from 'react'; +import Header from './../Header/Header.js'; +import Footer from './../Footer/Footer.js'; + +import './AboutUs.css' + +export default class AboutUs extends Component { + render(){ + return ( +
+
+
+

+
About
+

+

STSI LearningLab is a web application developed by two interns at STSI, Jimmy Flores and Emmett Dorlester, with the mentorship of STSI Employees Kevin Melendez and Ben Morris. The idea of LearningLab is to create a set of web applications to run on a Raspberry Pi, web applications consisting of a Weather App, a Traffic App, and more.

+
+
+ ); + } +} diff --git a/src/components/AboutUs/AboutUs.test.js b/src/components/AboutUs/AboutUs.test.js new file mode 100644 index 00000000..10d250df --- /dev/null +++ b/src/components/AboutUs/AboutUs.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import AboutUs from './AboutUs.js'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/src/components/App.js b/src/components/App.js index 5bfdb809..ee7b868b 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,60 +1,28 @@ import React, { Component } from 'react'; -import Header from './Header/Header.js'; -import Footer from './Footer/Footer.js'; -import WeatherData from './WeatherCard/WeatherData.js'; -import TrafficCard from './TrafficCard/TrafficCard.js'; -import CardContainer from './CardContainer/CardContainer.js'; +import home from './home.js'; +import AboutUs from './AboutUs/AboutUs.js'; +import TrafficCardArchive from './CardArchive/TrafficCardArchive.js'; +import WeatherCardArchive from './CardArchive/WeatherCardArchive.js'; +import FullScreen from './FullScreen/FullScreen.js'; +import { + BrowserRouter as Router, + Route +} from 'react-router-dom' import './App.css'; export default class App extends Component { - constructor(props){ - super(props); - this.state = { - fixedCard: null - }; - } - render(){ - let cards = [ - , - - ]; - let cardToDropdown = (card, index) => ({ - label: card.props.menuLabel, - index: index - }); return ( +
-
{this.setState({fixedCard: index})}} - /> -
-
-
- {cards} -
-
-
+ + + + +
+ ); } } diff --git a/src/components/CardArchive/TrafficCardArchive.js b/src/components/CardArchive/TrafficCardArchive.js new file mode 100644 index 00000000..5f4d53c9 --- /dev/null +++ b/src/components/CardArchive/TrafficCardArchive.js @@ -0,0 +1,32 @@ +import React, { Component } from 'react'; +import Header from './../Header/Header.js'; +import Footer from './../Footer/Footer.js'; +import TrafficCard from './../TrafficCard/TrafficCard.js'; + +import './../App.css'; + + +export default class TrafficCardArchive extends Component { + render(){ + return ( +
+
+
+
+
+ +
+
+
+
+ ); + } +} diff --git a/src/components/CardArchive/TrafficCardArchive.test.js b/src/components/CardArchive/TrafficCardArchive.test.js new file mode 100644 index 00000000..dc531028 --- /dev/null +++ b/src/components/CardArchive/TrafficCardArchive.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import TrafficCardArchive from './TrafficCardArchive.js'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/src/components/CardArchive/WeatherCardArchive.js b/src/components/CardArchive/WeatherCardArchive.js new file mode 100644 index 00000000..5e7cd5db --- /dev/null +++ b/src/components/CardArchive/WeatherCardArchive.js @@ -0,0 +1,29 @@ +import React, { Component } from 'react'; +import Header from './../Header/Header.js'; +import Footer from './../Footer/Footer.js'; +import WeatherData from './../WeatherCard/WeatherData.js'; + +import './../App.css'; + + +export default class WeatherCardArchive extends Component { + render(){ + return ( +
+
+
+
+
+ +
+
+
+
+ ); + } +} diff --git a/src/components/CardArchive/WeatherCardArchive.test.js b/src/components/CardArchive/WeatherCardArchive.test.js new file mode 100644 index 00000000..6facfe7f --- /dev/null +++ b/src/components/CardArchive/WeatherCardArchive.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import WeatherCardArchive from './WeatherCardArchive.js'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/src/components/CardContainer/CardContainer.test.js b/src/components/CardContainer/CardContainer.test.js index 01a3d6ae..ba76dfb2 100644 --- a/src/components/CardContainer/CardContainer.test.js +++ b/src/components/CardContainer/CardContainer.test.js @@ -3,16 +3,17 @@ import ReactDOM from 'react-dom'; import { Card } from 'semantic-ui-react'; import CardContainer from './CardContainer.js'; +const DummyCard = (props) => ( + + + {props.header} + {props.description} + + +); + it('transitions between cards without crashing', (done) => { const div = document.createElement('div'); - const DummyCard = (props) => ( - - - {props.header} - {props.description} - - - ); ReactDOM.render( @@ -24,3 +25,33 @@ it('transitions between cards without crashing', (done) => { done(); }, 3000); }); + +it('sets and clears fixed card without crashing', (done) => { + const div = document.createElement('div'); + ReactDOM.render( + + + + + , div); + setTimeout(() => { + ReactDOM.render( + + + + + , div); + setTimeout(() => { + ReactDOM.render( + + + + + , div); + setTimeout(() => { + ReactDOM.unmountComponentAtNode(div); + done(); + }, 1000); + }, 1000); + }, 1000); +}); diff --git a/src/components/FullScreen/FullScreen.js b/src/components/FullScreen/FullScreen.js new file mode 100644 index 00000000..cf9b8423 --- /dev/null +++ b/src/components/FullScreen/FullScreen.js @@ -0,0 +1,41 @@ +import React, { Component } from 'react'; +import FullScreenHeader from './../FullScreenHeader/FullScreenHeader.js'; +import WeatherData from './../WeatherCard/WeatherData.js'; +import TrafficCard from './../TrafficCard/TrafficCard.js'; +import CardContainer from './../CardContainer/CardContainer.js'; + +export default class home extends Component { + render(){ + let cards = [ + , + + ]; + return ( +
+ +
+
+
+ {cards} +
+
+
+ ); + } +} diff --git a/src/components/FullScreen/FullScreen.test.js b/src/components/FullScreen/FullScreen.test.js new file mode 100644 index 00000000..ba5b8e74 --- /dev/null +++ b/src/components/FullScreen/FullScreen.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import FullScreen from './FullScreen.js'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/src/components/FullScreenHeader/FullScreenHeader.css b/src/components/FullScreenHeader/FullScreenHeader.css new file mode 100644 index 00000000..5bf129a7 --- /dev/null +++ b/src/components/FullScreenHeader/FullScreenHeader.css @@ -0,0 +1,34 @@ +.ui.menu { + background-color: #333333; + border-width: 0px !important; + border-radius: 0 0 .28571429rem .28571429rem !important; +} + +/* .ui.menu .ui.dropdown .menu > .item { + background-color: #333333 !important; + color: white !important; +} */ + +.item { + color: white !important; +} + +a.item:hover { + background-color: #f25253 !important; + color: white !important; + border-radius: 0 0 0 0 !important; +} + +.ui.menu .ui.dropdown.item .menu .item:not(.filtered):hover { + color: #f25253 !important; + background-color: #FFFFFF !important; +} + +.ui.menu>.item:first-child:hover { + background-color: #f25253 !important; +} + +div.ui.item.dropdown:hover { + background-color: #f25253 !important; + color: white !important; +} diff --git a/src/components/FullScreenHeader/FullScreenHeader.js b/src/components/FullScreenHeader/FullScreenHeader.js new file mode 100644 index 00000000..3e211e92 --- /dev/null +++ b/src/components/FullScreenHeader/FullScreenHeader.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react' +import { Menu, Grid } from 'semantic-ui-react' + +import './FullScreenHeader.css'; + +export default class Header extends Component { + render(){ + return ( + + + + STSI + + + + ); + } +} diff --git a/src/components/FullScreenHeader/FullScreenHeader.test.js b/src/components/FullScreenHeader/FullScreenHeader.test.js new file mode 100644 index 00000000..5b1fa8dc --- /dev/null +++ b/src/components/FullScreenHeader/FullScreenHeader.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import FullScreenHeader from './FullScreenHeader.js'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css index 94e4e85f..5bf129a7 100644 --- a/src/components/Header/Header.css +++ b/src/components/Header/Header.css @@ -19,12 +19,16 @@ a.item:hover { border-radius: 0 0 0 0 !important; } -div.ui.item.dropdown:hover { +.ui.menu .ui.dropdown.item .menu .item:not(.filtered):hover { + color: #f25253 !important; + background-color: #FFFFFF !important; +} + +.ui.menu>.item:first-child:hover { background-color: #f25253 !important; - color: white !important; } -.ui.menu .ui.dropdown .menu>.item:hover { - background-color: #FFF !important; - color: #f25253 !important; +div.ui.item.dropdown:hover { + background-color: #f25253 !important; + color: white !important; } diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js index 2f1123fe..61f4be3c 100644 --- a/src/components/Header/Header.js +++ b/src/components/Header/Header.js @@ -3,16 +3,7 @@ import { Menu, Dropdown } from 'semantic-ui-react' import './Header.css'; - export default class Header extends Component { - constructor(props){ - super(props); - this.state = { - activeItem: null - }; - this.handleItemClick = this.handleItemClick.bind(this); - } - handleItemClick(event, {name}){ this.setState({ activeItem: name @@ -20,32 +11,37 @@ export default class Header extends Component { } render(){ - let makeDropdownItem = (entry) => ( - this.props.onChange(entry.index)} key={entry.label}> - {entry.label} - - ); return ( - {this.props.onChange(null)}}> - STSI + + STSI - {this.props.cardEntries.map(makeDropdownItem)} + +

Weather Card

+
+ +

Traffic Card

+
+ + />
); diff --git a/src/components/WeatherCard/APIfuncs.test.js b/src/components/WeatherCard/APIfuncs.test.js index 2c30f155..25903679 100644 --- a/src/components/WeatherCard/APIfuncs.test.js +++ b/src/components/WeatherCard/APIfuncs.test.js @@ -4,5 +4,13 @@ describe('parseCity', () => { it('handles missing data', () => { expect(parseCity({})).toEqual({}); }); - //add more? + it('extracts the city name correctly', () => { + expect(parseCity({ + results: [{ + formatted_address: 'Test City, US 01234' + }] + })).toEqual({ + city: 'Test City, US' + }); + }); }); diff --git a/src/components/home.js b/src/components/home.js new file mode 100644 index 00000000..5591dfee --- /dev/null +++ b/src/components/home.js @@ -0,0 +1,52 @@ +import React, { Component } from 'react'; +import Header from './Header/Header.js'; +import Footer from './Footer/Footer.js'; +import WeatherData from './WeatherCard/WeatherData.js'; +import TrafficCard from './TrafficCard/TrafficCard.js'; +import CardContainer from './CardContainer/CardContainer.js'; + +import './App.css'; + +export default class home extends Component { + render(){ + let cards = [ + , + + ]; + let cardToDropdown = (card, index) => ({ + label: card.props.menuLabel, + index: index + }); + + return ( +
+
+
+
+
+ {cards} +
+
+
+
+ ); + } +} diff --git a/src/index.css b/src/index.css index 6a1b9220..5c7fea2f 100644 --- a/src/index.css +++ b/src/index.css @@ -1,9 +1,20 @@ body { - border-radius: 25px; - margin: 0; - padding: 0; - font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; - background: - url('./images/blurred-background-5.jpg'); - background-size: cover; + border-radius: 25px; + margin: 0; + padding: 0; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + background: url('./images/blurred-background-5.jpg'); + background-size: cover; +} + +div { + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.aboutUs-bg { + background: white; + height: 100vh; } diff --git a/src/index.js b/src/index.js index 4c4b3f6c..d2319df0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,12 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import { + BrowserRouter as Router +} from 'react-router-dom' import './index.css'; import App from './components/App'; -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render(( + + +), document.getElementById('root'));