diff --git a/.DS_Store b/.DS_Store index 729469a..f14dec1 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/myapp/package-lock.json b/myapp/package-lock.json index 0c13121..321aab5 100644 --- a/myapp/package-lock.json +++ b/myapp/package-lock.json @@ -1320,6 +1320,11 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==" }, + "base64url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz", + "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs=" + }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -4984,6 +4989,57 @@ "assert-plus": "1.0.0" } }, + "gh-pages": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-1.1.0.tgz", + "integrity": "sha512-ZpDkeOVmIrN5mz+sBWDz5zmTqcbNJzI/updCwEv/7rrSdpTNlj1B5GhBqG7f4Q8p5sJOdnBV0SIqxJrxtZQ9FA==", + "requires": { + "async": "2.6.0", + "base64url": "2.0.0", + "commander": "2.11.0", + "fs-extra": "4.0.3", + "globby": "6.1.0", + "graceful-fs": "4.1.11", + "rimraf": "2.6.2" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "4.1.11" + } + } + } + }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", diff --git a/myapp/package.json b/myapp/package.json index 2d24d5c..bc1b8f5 100644 --- a/myapp/package.json +++ b/myapp/package.json @@ -4,16 +4,20 @@ "private": true, "dependencies": { "firebase": "^4.10.1", + "gh-pages": "^1.1.0", "react": "^16.2.0", "react-dom": "^16.2.0", "react-router-dom": "^4.2.2", "react-scripts": "1.1.1", "recharts": "^1.0.0-beta.10" }, + "homepage": "https://students.washington.edu/evanzhao/info343/p4-climbingApp/", "scripts": { + "predeploy": "npm run build", + "deploy": "gh-pages -d build", "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" } -} +} \ No newline at end of file diff --git a/myapp/src/App.css b/myapp/src/App.css index 5660ac2..71cef39 100644 --- a/myapp/src/App.css +++ b/myapp/src/App.css @@ -55,7 +55,7 @@ nav { text-align: center; } -h1, footer { +h1 { margin: 0; padding: 1.5vh; padding-left: 1.5vw; @@ -147,10 +147,18 @@ button { } button:after { - content: '\00bb'; + /* content: '\00bb'; */ position: absolute; opacity: 0; top: 0; - right: -20px; + /* right: -20px; */ transition: 0.5s; +} + +footer { + bottom: 0; + position: fixed; + padding-left: 1rem; + padding-bottom: 0; + margin-bottom: 0; } \ No newline at end of file diff --git a/myapp/src/App.js b/myapp/src/App.js index eb7324d..c15d1ce 100644 --- a/myapp/src/App.js +++ b/myapp/src/App.js @@ -5,36 +5,84 @@ import firebase from 'firebase'; import 'firebase/auth'; import 'firebase/database'; import { PieChart, Pie, Cell } from 'recharts'; -import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; +import { BrowserRouter as Router, Route } from 'react-router-dom'; import { NavLink } from 'react-router-dom'; + +//Renders the website class App extends Component { - constructor(props) { - super(props); + constructor() { + super(); + this.handleLogout = this.handleLogout.bind(this); + this.handleUser = this.handleUser.bind(this); + this.state = { + user: '' + }; } + //Handles Logout + handleLogout() { + this.setState({ + user: '' + }); + firebase.auth().signOut() + .catch((err) => { + console.log(err) + }) + } + + handleUser(data) { + this.setState({ + user: data + }); + } + + //Renders Header and Nav Links to other parts of the website render() { return (
- {/*

Find your Climb!

*/} +

Find your Climb!

+ {this.state.user !== '' && + +
Profile
+
+ } +
Routes
Types
- -
Login
-
+ {this.state.user === '' ? + +
Login
+
+ : + + } - - + {this.state.user === '' ? + ( + + )} /> + : + ( + + )} /> + } + ( + + )} /> + ( + + )} />
@@ -43,6 +91,7 @@ class App extends Component { } } +//Renders the homepage class WelcomePage extends Component { render() { return ( @@ -56,6 +105,7 @@ class WelcomePage extends Component { } } +//Renders the login page class LoginPage extends Component { constructor(props) { super(props); @@ -68,6 +118,7 @@ class LoginPage extends Component { componentDidMount() { this.stopWatchingAuth = firebase.auth().onAuthStateChanged(firebaseUser => { if (firebaseUser) { + // this.props.history.push("/routes"); this.setState({ user: firebaseUser, errorMessage: '', @@ -75,12 +126,18 @@ class LoginPage extends Component { password: '', username: '' }); + this.props.handlerFromParent(this.state.user); } else { this.setState({ user: null }); //null out the saved state } }) } + componentWillUnmount() { + this.stopWatchingAuth(); + } + + //Function that signs user up and stores their data in firebase handleSignUp() { /* Create a new user and save their information */ @@ -103,31 +160,22 @@ class LoginPage extends Component { this.setState({ errorMessage: err.message }) }) } + + handleSignIn() { //A callback function for logging in existing users - /* Sign in the user */ firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password) - .catch((err) => { - console.log(err) - this.setState({ errorMessage: err.message }) - }); - - } - - handleSignOut() { - this.setState({ errorMessage: null }); //clear old error - - /* Sign out the user, and update the state */ - firebase.auth().signOut() - .then(() => { - this.setState({ user: null }); //null out the saved state + .then(user => { + this.setState({ + user: user + }) }) .catch((err) => { - console.log(err) + console.log(err.message) this.setState({ errorMessage: err.message }) - }) + }); } handleChange(event) { @@ -185,9 +233,9 @@ class LoginPage extends Component { - + */}
); @@ -195,6 +243,7 @@ class LoginPage extends Component { } //skykomish valley +//Default numbers for when website is first rendered const DEFAULTS = { lat: '47.8207', lon: '-121.5551', @@ -202,6 +251,7 @@ const DEFAULTS = { maxDist: 10 }; +//Renders the page that shows routes class RoutesPage extends Component { constructor(props) { @@ -209,6 +259,7 @@ class RoutesPage extends Component { this.loadData(DEFAULTS.lat, DEFAULTS.lon, DEFAULTS.numRoutes, DEFAULTS.maxDist) } + //Brings the data from the mountain project.com using an api call loadData(lat, lon, numRoutes, maxDist) { let url = "https://www.mountainproject.com/data/get-routes-for-lat-lon?key=200219054-5692fe76fab0e0f8dbdddb64cba1f33b&lat=" + lat + "&lon=" + lon + "&maxDistance=" + maxDist + "&maxResults=" + numRoutes; fetch(url) @@ -237,7 +288,7 @@ class RoutesPage extends Component { this.handleSubmit(latLongParams)} />
- +
@@ -249,11 +300,13 @@ class RoutesPage extends Component { } } +//The card that shows the data of the rock climbing areas class ClimbCard extends React.Component { - constructor() { - super() + constructor(props) { + super(props) this.state = { - isHidden: true + isHidden: true, + likes: '' } } toggleHidden() { @@ -261,7 +314,76 @@ class ClimbCard extends React.Component { isHidden: !this.state.isHidden }) } + + + //Counts the number of likes per location and stores it on firebase + countLikesToFireBase() { + + firebase.database().ref('Post/' + this.props.id + "/Likes").transaction(function (Likes) { + console.log("likes", Likes); + if (Likes) { + + Likes = Likes + 1; + } else { + Likes = 1; + } + return Likes; + }); + + } + + + //Saves a location that the user chose on firebase so that it can be viewed on their profile later + pushLikeToFireBase() { + let UserRef = firebase.database().ref('Users'); + let dataName = this.props.name; + let foundKey = false; + Object.keys(UserRef).forEach((key) => { + if (key === this.props.uid) { + foundKey = true; + UserRef.child(key).child('Climbs').push({ + Name: this.props.name, + Type: this.props.type, + Rating: this.props.rating, + Stars: this.props.stars, + Pitches: this.props.pitches, + Location: this.props.location, + Image: this.props.img, + Id: this.props.id + + }).catch(err => console.log(err)); + } + } + ) + if (!foundKey) { + firebase.database().ref('Users/' + this.props.uid + '/Climbs/' + this.props.id + "/").set( + { + Name: this.props.name, + Type: this.props.type, + Rating: this.props.rating, + Stars: this.props.stars, + Pitches: this.props.pitches, + Location: this.props.location, + Image: this.props.img, + Id: this.props.id + } + ).catch(err => console.log(err)); + } + + foundKey = false; + } + + + componentDidMount() { + firebase.database().ref('Post/' + this.props.id + "/Likes").on('value', (snapshot) => { + this.setState({ + likes: snapshot.val() + }); + }) + } + render() { + console.log(this.props.uid) let pitches = this.props.pitches; if (pitches === '') { pitches = "N/A"; @@ -279,25 +401,39 @@ class ClimbCard extends React.Component {

Stars: {this.props.stars}

Pitches: {pitches}

Location: {this.props.location}

+

Likes: {this.state.likes === '' ? "0" : this.state.likes}

+ {this.props.uid === '' && + + + } + {this.props.uid !== '' && + + + } + {this.props.uid !== '' && + + + } + } + ) } } +//Generates a list of card climbing routes and the pie chart class ClimbList extends React.Component { render() { let dict = _(this.props.routes) .countBy('type') .value() - let arr = []; let combined = 0; Object.keys(dict).forEach((key) => { - console.log(key, dict[key]); if (!key.includes(',')) { arr.push({ name: key, value: dict[key] }) } else { @@ -317,6 +453,7 @@ class ClimbList extends React.Component { return color; } + let colorArray = []; for (let i = 0; i < 5; i++) { colorArray[i] = getRandomColor(); @@ -329,19 +466,11 @@ class ClimbList extends React.Component { outerRadius={200} innerRadius={180} label={(something) => something.name} > - - - - - - - -
@@ -351,7 +480,7 @@ class ClimbList extends React.Component {
{ this.props.routes.map((climb) => - ) }
@@ -360,6 +489,8 @@ class ClimbList extends React.Component { } } + +// Takes in the user entered parameters and renders the form to submit them in class ClimbParam extends React.Component { constructor(props) { super(props); @@ -405,7 +536,7 @@ class ClimbParam extends React.Component { onChange={this.handleChange} />
- +

Notable Locations:

@@ -428,11 +559,18 @@ class ClimbParam extends React.Component {

Lat: 46.9454

Lon: -119.9873

+
+
SmithRock
+

Lat: 44.3682

+

Lon: -121.1406

+
); } } + +//Renders the about page containing information on types of bouldering class AboutPage extends Component { render() { @@ -489,4 +627,50 @@ class AboutPage extends Component { } +//Redners the profile page which holds the user's saved climbing routes +class ProfilePage extends Component { + constructor(props) { + super(props) + this.state = { + climbs: '' + } + } + + componentDidMount() { + if (this.props.uid !== undefined) { + let ref = firebase.database().ref('Users').child(this.props.uid).child('Climbs'); + ref.on('value', (snapshot) => { + this.setState({ + climbs: snapshot.val() + }); + console.log(this.state.climbs); + + console.log(snapshot.val()) + }) + + } + } + + render() { + return ( + + < div > +

Welcome to your Profile!

+

Here are your saved climbs!

+
+
+ + {this.state.climbs !== null && + Object.keys(this.state.climbs).map((climb) => + // console.log(this.state.climbs[climb])) + < ClimbCard uid={this.props.uid} key={this.state.climbs[climb].Id} id={this.state.climbs[climb].Id} img={this.state.climbs[climb].Image} name={this.state.climbs[climb].Name} type={this.state.climbs[climb].Type} + rating={this.state.climbs[climb].Rating} stars={this.state.climbs[climb].Stars} pitches={this.state.climbs[climb].Pitches} location={this.state.climbs[climb].Location} />) + } + +
+
+ + ); + } +} export default App;