diff --git a/package.json b/package.json
index a8ae1ad..e45497e 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"firebase-admin": "^6.0.0",
"flamelink": "^0.19.2",
"google-maps-react": "^2.0.2",
+ "moment": "^2.22.2",
"react": "^16.5.1",
"react-dom": "^16.5.1",
"react-quiz-component": "0.2.0",
diff --git a/src/components/QuizGame.js b/src/components/QuizGame.js
index bbfe640..1339978 100644
--- a/src/components/QuizGame.js
+++ b/src/components/QuizGame.js
@@ -3,21 +3,9 @@ import Grid from '@material-ui/core/Grid';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Quiz from 'react-quiz-component';
-
-/**
- * Shuffles a given array.
- * @param {*} array The array passed in.
- */
-function shuffleArray(array) {
- var j, x, i;
- for (i = array.length - 1; i > 0; i--) {
- j = Math.floor(Math.random() * (i + 1));
- x = array[i];
- array[i] = array[j];
- array[j] = x;
- }
- return array;
-}
+import { Typography } from '@material-ui/core';
+import Button from '@material-ui/core/Button';
+import RefreshIcon from '@material-ui/icons/Refresh';
// Style for the tabs.
const styles = theme => ({
@@ -25,13 +13,45 @@ const styles = theme => ({
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
},
+ button: {
+ margin: theme.spacing.unit,
+ },
+ rightIcon: {
+ marginLeft: theme.spacing.unit,
+ },
});
class QuizGame extends React.Component {
+ /**
+ * Shuffles a given array.
+ * @param {*} array The array passed in.
+ */
+ shuffleArray = array => {
+ let shuffled = array;
+
+ var j, x, i;
+
+ for (i = shuffled.length - 1; i > 0; i--) {
+ j = Math.floor(Math.random() * (i + 1));
+ x = shuffled[i];
+ shuffled[i] = shuffled[j];
+ shuffled[j] = x;
+ }
+
+ return shuffled;
+ }
+
+ reset = () => {
+ this.setState({
+ difficulty: this.pickDifficulty(this.props.difficulty),
+ key: Math.random()
+ });
+ }
+
easy = {
"quizTitle": "Trail Cam Quiz: Easy",
- "questions": shuffleArray([
+ "questions": [
{
"question": What animal is this?
,
"questionType": "text",
@@ -87,12 +107,12 @@ class QuizGame extends React.Component {
],
"correctAnswer": "3"
},
- ])
+ ]
}
medium = {
"quizTitle": "Trail Cam Quiz: Medium",
- "questions": shuffleArray([
+ "questions": [
{
"question": What animal is this?
,
"questionType": "text",
@@ -148,12 +168,12 @@ class QuizGame extends React.Component {
],
"correctAnswer": "3"
},
- ])
+ ]
}
hard = {
"quizTitle": "Trail Cam Quiz: Hard",
- "questions": shuffleArray([
+ "questions": [
{
"question": What animal is this?
,
"questionType": "text",
@@ -209,20 +229,29 @@ class QuizGame extends React.Component {
],
"correctAnswer": "3"
},
- ])
+ ]
}
+ /**
+ * This function returns the
+ * quiz data based on the difficulty
+ * level passed into it.
+ * @param {*} difficulty The difficulty setting passed in.
+ */
pickDifficulty = difficulty => {
let level
switch (difficulty) {
case 'Easy':
+ this.easy.questions = this.shuffleArray(this.easy.questions)
level = this.easy
break
case 'Medium':
+ this.medium.questions = this.shuffleArray(this.medium.questions)
level = this.medium
break
case 'Hard':
+ this.hard.questions = this.shuffleArray(this.hard.questions)
level = this.hard
break
default:
@@ -234,8 +263,8 @@ class QuizGame extends React.Component {
// The state of the component.
state = {
- //difficulty: pickDifficulty(this.props.difficulty)
- difficulty: this.pickDifficulty(this.props.difficulty)
+ difficulty: this.pickDifficulty(this.props.difficulty),
+ key: Math.random()
}
// Renders the quiz component.
@@ -245,9 +274,17 @@ class QuizGame extends React.Component {
return (
// Tabs
-
-
-
+
+
+
+
+
+
+
+
);
}
diff --git a/src/components/ReportForm.js b/src/components/ReportForm.js
index 9815843..7d50473 100644
--- a/src/components/ReportForm.js
+++ b/src/components/ReportForm.js
@@ -4,6 +4,10 @@ import Grid from '@material-ui/core/Grid';
import { withStyles } from '@material-ui/core/styles';
import MenuItem from '@material-ui/core/MenuItem';
import TextField from '@material-ui/core/TextField';
+import CheckCircleIcon from '@material-ui/icons/CheckCircle';
+import Snackbar from '@material-ui/core/Snackbar';
+import IconButton from '@material-ui/core/IconButton';
+import CloseIcon from '@material-ui/icons/Close';
import Button from '@material-ui/core/Button';
import firebase from '../firebase.js';
import GoogleMap from '../components/ReportMap';
@@ -33,6 +37,17 @@ const styles = theme => ({
dense: {
marginTop: 30,
},
+ close: {
+ padding: theme.spacing.unit / 2,
+ },
+ icon: {
+ fontSize: 20,
+ marginRight: theme.spacing.unit,
+ },
+ message: {
+ display: 'flex',
+ alignItems: 'center',
+ },
menu: {
width: 200,
},
@@ -220,7 +235,8 @@ class ReportForm extends React.Component {
confidence: '1',
desc: '',
lat: '',
- lng: ''
+ lng: '',
+ open: false
};
/**
@@ -233,6 +249,17 @@ class ReportForm extends React.Component {
});
};
+ /**
+ * Handles closing the toast.
+ */
+ handleClose = (event, reason) => {
+ if (reason === 'clickaway') {
+ return;
+ }
+
+ this.setState({ open: false });
+ };
+
/*
* Get the coordinates
*
@@ -274,7 +301,8 @@ class ReportForm extends React.Component {
confidence: '1',
desc: '',
lat: '',
- lng: ''
+ lng: '',
+ open: true
});
};
@@ -440,6 +468,30 @@ class ReportForm extends React.Component {
+ Report received.}
+ action={[
+
+
+ ,
+ ]}
+ />
);
}
diff --git a/src/components/SightingMap.js b/src/components/SightingMap.js
index e2c3e89..5535b68 100644
--- a/src/components/SightingMap.js
+++ b/src/components/SightingMap.js
@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react';
import { Map, InfoWindow, Marker, GoogleApiWrapper } from 'google-maps-react';
+import moment from 'moment'
import Typography from '@material-ui/core/Typography';
import firebase from '../firebase.js';
@@ -12,6 +13,128 @@ const mapStyles = {
height: '100%'
}
+/**
+ * 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',
+ },
+];
+
+/**
+ * Types of sightings. Label is what is
+ * viewed in the application, value is
+ * what is stored in the database.
+*/
+const timeTypes = [
+ {
+ value: 'unknown',
+ label: 'Unknown',
+ },
+ {
+ value: 'morning',
+ label: 'Morning',
+ },
+ {
+ value: 'midday',
+ label: 'Midday',
+ },
+ {
+ value: 'evening',
+ label: 'Evening',
+ },
+ {
+ value: 'night',
+ label: 'Night',
+ },
+];
+
+/**
+ * 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',
+ },
+];
+
+/**
+ * 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
@@ -19,22 +142,22 @@ export class MapContainer extends Component {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
this.setState({
- myLatLng: {
- lat: position.coords.latitude,
- lng: position.coords.longitude
- }
+ myLatLng: {
+ lat: position.coords.latitude,
+ lng: position.coords.longitude
}
+ }
);
})
} else {
// If browser doesn't support geolocation or if user does not allow it,
// center map on Grand Rapids, Michigan
this.setState({
- myLatLng: {
- lat: 42.9634,
- lng: 85.6681
- }
+ myLatLng: {
+ lat: 42.9634,
+ lng: 85.6681
}
+ }
);
}
}
@@ -85,6 +208,10 @@ export class MapContainer extends Component {
}
}
+ formatDate = date => {
+ return (moment(date, "YYYY-MM").format("MMMM YYYY").toString())
+ }
+
// Set the state of the component to contain user coordinates and initial
// marker and info window information
state = {
@@ -101,55 +228,55 @@ export class MapContainer extends Component {
render() {
return (
// Render the Google Map, Marker, and InfoWindow components
-
+