diff --git a/package-lock.json b/package-lock.json index 14f5192..28c8d70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3488,6 +3488,16 @@ "sha.js": "^2.4.8" } }, + "create-react-class": { + "version": "15.6.3", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", + "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", + "requires": { + "fbjs": "^0.8.9", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -4005,6 +4015,40 @@ } } }, + "disqus-react": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/disqus-react/-/disqus-react-1.0.5.tgz", + "integrity": "sha1-go6hhr0kHF4qbf66tRNeUqLZHRE=", + "requires": { + "react": "^15.6.1", + "react-dom": "^15.6.1" + }, + "dependencies": { + "react": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz", + "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=", + "requires": { + "create-react-class": "^15.6.0", + "fbjs": "^0.8.9", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.0", + "prop-types": "^15.5.10" + } + }, + "react-dom": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", + "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=", + "requires": { + "fbjs": "^0.8.9", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.0", + "prop-types": "^15.5.10" + } + } + } + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", diff --git a/package.json b/package.json index 66d5b6a..f97d559 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@material-ui/core": "^3.1.0", "@material-ui/icons": "^3.0.1", "ajv": "^6.0.0", + "disqus-react": "^1.0.5", "firebase": "^5.5.2", "firebase-admin": "^6.1.0", "flamelink": "^0.19.2", diff --git a/src/App.css b/src/App.css index 9494272..b5b1e22 100644 --- a/src/App.css +++ b/src/App.css @@ -13,4 +13,38 @@ body { .report-google-map-container > div { width: calc(100% - 50% - 120px) !important; } +} + +#disqus_thread { + width: 89% !important; + margin: 0 auto; +} + +.sighting-list { + height: calc(50vh - 64px); + overflow-y: scroll; +} + +@media (min-width: 960px) { + .sighting-list { + height: calc(100vh - 64px); + overflow-y: scroll; + } +} + +.sighting-details-content { + width: 89%; + margin: 330px auto 0 auto; +} + +.sighting-detail-google-map-container > div { + width: 100% !important; + height: 300px !important; +} + +@media (min-width: 960px) { + .sighting-detail-google-map-container > div { + width: calc(100% - 50% - 120px) !important; + height: 300px !important; + } } \ No newline at end of file diff --git a/src/components/Main.js b/src/components/Main.js index 984555e..deb0343 100644 --- a/src/components/Main.js +++ b/src/components/Main.js @@ -155,7 +155,7 @@ class ResponsiveDrawer extends React.Component { - The American Marten + Marten Tracker diff --git a/src/components/ReportForm.js b/src/components/ReportForm.js index 7d50473..9068eec 100644 --- a/src/components/ReportForm.js +++ b/src/components/ReportForm.js @@ -53,19 +53,6 @@ const styles = theme => ({ }, }); -/** - * Function for formatting the - * year as a string that - * Material UI can use. - * @param {*} date, Date passed in. - */ -function getYear(date) { - var d = new Date(date), - year = d.getFullYear(); - - return year; -} - /** * Types of sightings. Label is what is * viewed in the application, value is @@ -224,12 +211,44 @@ class ReportForm extends React.Component { this.handleSubmit = this.handleSubmit.bind(this); } + /** + * Function for formatting the + * year as a string that + * Material UI can use. + * @param {*} date, Date passed in. + */ + getYear = date => { + var d = new Date(date), + year = d.getFullYear(); + + return year; +} + +/** +* Function for formatting the +* month as a string that +* Material UI can use. +* @param {*} date, Date passed in. +*/ +getMonth = date => { + var d = new Date(date), + month = d.getMonth() + 1; + + month = month.toString(); + + if (month.length === 1) { + month = "0" + month; + } + + return month; +} + /** * State of form components. */ state = { - month: '01', - year: getYear(new Date()), + month: this.getMonth(new Date()), + year: this.getYear(new Date()), time: 'unknown', type: 'visual', confidence: '1', @@ -294,8 +313,8 @@ class ReportForm extends React.Component { } sightingsRef.push(sighting); this.setState({ - year: getYear(new Date()), - month: '01', + year: this.getYear(new Date()), + month: this.getMonth(new Date()), time: 'unknown', type: 'visual', confidence: '1', @@ -479,7 +498,7 @@ class ReportForm extends React.Component { ContentProps={{ 'aria-describedby': 'message-id', }} - message={Report received.} + message={Report received.} action={[ + +
+

{`Confidence: ${this.props.detail.confidence}`}

+

{`When: ${this.props.detail.date}, ${this.props.detail.time}`}

+

{`Where: ${this.props.detail.lat} degrees N, and ${this.props.detail.lng} degrees E`}

+

{`${this.props.detail.desc}`}

+
+ + + ); + } +} + +export default SightingDetail; diff --git a/src/components/SightingDetailMap.js b/src/components/SightingDetailMap.js new file mode 100644 index 0000000..aaa4c50 --- /dev/null +++ b/src/components/SightingDetailMap.js @@ -0,0 +1,38 @@ +import React, { Component } from 'react'; +import { Map, Marker, GoogleApiWrapper } from 'google-maps-react'; + +// Google Maps API Key +const API_KEY = 'AIzaSyAZ_0J01bA6wCbIPK4UBq2RUBC-hIqG4mM'; + +// Map container styles +const mapStyles = { + width: '100%', + height: '100%' +} + +export class MapContainer extends Component { + + render() { + return ( + // Render the Google Map, Marker, and InfoWindow components +
+ + + + +
+ ); + } +} + +// Send the Google Map API Key with the MapContainer component +export default GoogleApiWrapper({ + apiKey: (API_KEY) +})(MapContainer) \ No newline at end of file diff --git a/src/components/SightingMap.js b/src/components/SightingMap.js index 5535b68..2d00465 100644 --- a/src/components/SightingMap.js +++ b/src/components/SightingMap.js @@ -101,40 +101,6 @@ const confidenceLevels = [ }, ]; -/** - * Gets formatted confidence value. - */ -function getConfidence(item) { - for (var i = 0; i < confidenceLevels.length; i++) { - if (confidenceLevels[i].value === item) { - return confidenceLevels[i].label; - } - } - -} - -/** - * Gets formatted time value. - */ -function getTime(item) { - for (var i = 0; i < timeTypes.length; i++) { - if (timeTypes[i].value === item) { - return timeTypes[i].label; - } - } -} - -/** - * Gets formatted type value. - */ -function getType(item) { - for (var i = 0; i < sightingTypes.length; i++) { - if (sightingTypes[i].value === item) { - return sightingTypes[i].label; - } - } -} - export class MapContainer extends Component { // Get the user's location using Google's geolocation @@ -162,6 +128,41 @@ export class MapContainer extends Component { } } + /** + * Gets formatted type value. + */ + getType = item => { + for (var i = 0; i < sightingTypes.length; i++) { + if (sightingTypes[i].value === item) { + return sightingTypes[i].label; + } + } + } + + + /** + * Gets formatted time value. + */ + getTime = item => { + for (var i = 0; i < timeTypes.length; i++) { + if (timeTypes[i].value === item) { + return timeTypes[i].label; + } + } + } + + /** + * Gets formatted confidence value. + */ + getConfidence = item => { + for (var i = 0; i < confidenceLevels.length; i++) { + if (confidenceLevels[i].value === item) { + return confidenceLevels[i].label; + } + } + + } + // When the component has mounted to the DOM, get the user's location componentDidMount() { this.getLocation(); @@ -246,14 +247,14 @@ export class MapContainer extends Component { {this.state.sightings.map((sighting) => { return ( Confidence: {getConfidence(sighting.confidence)}} - date = {Date: {this.formatDate(sighting.date)}} - time = {Time: {getTime(sighting.time)}} - description = {Description: {sighting.desc}} + key={sighting.id} + position={{ lat: sighting.lat, lng: sighting.lng }} + onClick={this.onMarkerClick} + type={'Type: ' + this.getType(sighting.type)} + confidence={Confidence: {this.getConfidence(sighting.confidence)}} + date={Date: {this.formatDate(sighting.date)}} + time={Time: {this.getTime(sighting.time)}} + description={Description: {sighting.desc}} /> ) })} diff --git a/src/components/ViewSightings.js b/src/components/ViewSightings.js index 822cf8e..e245e6b 100644 --- a/src/components/ViewSightings.js +++ b/src/components/ViewSightings.js @@ -1,232 +1,95 @@ -import React, {Fragment} from 'react'; -import PropTypes from 'prop-types'; +import React, { Component, Fragment } from 'react'; import Grid from '@material-ui/core/Grid'; -import TextField from '@material-ui/core/TextField' -import Button from '@material-ui/core/Button' -import Paper from '@material-ui/core/Paper' -import { withStyles } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; import firebase from '../firebase.js'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import SightingDetail from './SightingDetail'; -const styles = theme => ({ - root: { - ...theme.mixins.gutters(), - paddingTop: theme.spacing.unit * 2, - paddingBottom: theme.spacing.unit * 2, - }, - container: { - display: 'flex', - flexWrap: 'wrap', - }, - textField: { - marginLeft: theme.spacing.unit * 2, - marginRight: theme.spacing.unit * 2, - marginTop: theme.spacing.unit * 2, - flexBasis: 280, - }, - button: { - marginLeft: theme.spacing.unit * 3, - marginRight: theme.spacing.unit * 3, - marginTop: theme.spacing.unit * 3, - }, - paper: { - marginLeft: theme.spacing.unit * 2, - marginRight: theme.spacing.unit, - marginTop: theme.spacing.unit * 2, - }, - }); +class ViewSightings extends Component { - /** - * Types of sightings. Label is what is - * viewed in the application, value is - * what is stored in the database. - */ - const sightingTypes = [ - { - value: 'visual', - label: 'Visual', - }, - { - value: 'roadkill', - label: 'Roadkill', - }, - { - value: 'trapped', - label: 'Trapped', - }, - { - value: 'viewed_tracks', - label: 'Viewed Tracks', - }, - { - value: 'photo', - label: 'Photo', - }, - { - value: 'other', - label: 'Other', - }, - ]; - - /** - * Levels of confidence. Label is what is - * viewed in the application, value is - * what is stored in the database. - */ - const confidenceLevels = [ - { - value: '1', - label: '1 - Strongly unconfident', - }, - { - value: '2', - label: '2 - Unconfident', - }, - { - value: '3', - label: '3 - Somewhat confident', - }, - { - value: '4', - label: '4 - Confident', - }, - { - value: '5', - label: '5 - Very confident', - }, - ]; + componentDidMount() { + const sightingsRef = firebase.database().ref('sightings'); - /** - * Gets formatted confidence value. - */ - function getConfidence(item) { - for (var i = 0; i < confidenceLevels.length; i++) { - if (confidenceLevels[i].value === item) { - return confidenceLevels[i].label; + sightingsRef.on('value', (snapshot) => { + let sightings = snapshot.val(); + let newState = []; + + for (let sighting in sightings) { + newState.push({ + id: sighting, + lat: sightings[sighting].lat, + lng: sightings[sighting].lng, + desc: sightings[sighting].desc, + type: sightings[sighting].type, + confidence: sightings[sighting].confidence, + date: sightings[sighting].date, + time: sightings[sighting].time + }); } - } - + this.setState({ + sightings: newState + }); + }); } - /** - * Gets formatted type value. - */ - function getType(item) { - for (var i = 0; i < sightingTypes.length; i++) { - if (sightingTypes[i].value === item) { - return sightingTypes[i].label; - } - } - } - -class ViewSightings extends React.Component { - constructor(props){ - super(props); - - this.handleSubmit = this.handleSubmit.bind(this); + getDetail = (id, lat, lng, desc, type, confidence, date, time) => { + this.setState({ + selectedSighting: { + id: id, + lat: lat, + lng: lng, + desc: desc, + type: type, + confidence: confidence, + date: date, + time: time + }, + clicked: true + }) } state = { - id: '', - type: 'N/A', - confidence: 'N/A', - date: 'N/A', - time: 'N/A', - desc: 'N/A', - lat: 'N/A', - lng: 'N/A' - }; - + sightings: [], + selectedSighting: { + id: null, + lat: null, + lng: null, + desc: null, + type: null, + confidence: null, + date: null, + time: null + }, + clicked: false + } - /** - * Handles state change. - */ - handleChange = name => event => { - this.setState({ - [name]: event.target.value, - }); - }; - - /** - * Handles submit on search. - */ - handleSubmit(e){ - e.preventDefault(); - const itemSighting = firebase.database().ref("sightings/" + this.state.id); - itemSighting.once("value").then((snapshot) => { - // Die if there's no data for that ID. - if (!snapshot.exists()) { - return; - } - - let data = snapshot.val(); - - this.setState({ - date: data.date, - time: data.time, - type: getType(data.type), - confidence: getConfidence(data.confidence), - desc: data.desc, - lat: data.lat, - lng: data.lng - }); - }); - }; - - render(){ - const { classes } = this.props; + render() { return ( - /** - * The below houses the search - * and submit button along with - * the sighting information - * it pulls. - */ - -
- - + + + + + { + this.state.sightings.map((sighting) => { + return ( + this.getDetail(sighting.id, sighting.lat, sighting.lng, sighting.desc, sighting.type, sighting.confidence, sighting.date, sighting.time)}> + + + ) + }) + } + + - - - - - - - - Sighting - - - Type: {this.state.type} {
} - Confidence: {this.state.confidence} {
} - Date: {this.state.date} {
} - Time: {this.state.time} {
} - Latitude: {this.state.lat} {
} - Longitude: {this.state.lng} {
} - Description: {this.state.desc} -
-
+ + {this.state.clicked === true && }
- ) - + ); } - } -ViewSightings.propTypes = { - classes: PropTypes.object.isRequired, - }; - -export default withStyles(styles)(ViewSightings); \ No newline at end of file +export default ViewSightings; \ No newline at end of file diff --git a/src/pages/Info.js b/src/pages/Info.js index 1642662..d55633f 100644 --- a/src/pages/Info.js +++ b/src/pages/Info.js @@ -1,5 +1,4 @@ import React, { Component, Fragment } from 'react'; -import Typography from '@material-ui/core/Typography'; import FlameLinkComponentCreations from '../components/FlameLinkComponentCreations'; import flamelinkApp from '../flamelink.js'; @@ -23,11 +22,6 @@ class Info extends Component { return (
- - - Info - - diff --git a/src/pages/SightingList.js b/src/pages/SightingList.js index 9d035b9..0540527 100644 --- a/src/pages/SightingList.js +++ b/src/pages/SightingList.js @@ -1,13 +1,10 @@ import React, { Component } from 'react'; import ViewSightings from '../components/ViewSightings.js'; -import Typography from '@material-ui/core/Typography'; class Sighting extends Component { render() { return ( - - - + ); } }