diff --git a/client/actions/index.js b/client/actions/index.js
new file mode 100644
index 0000000..672a7f8
--- /dev/null
+++ b/client/actions/index.js
@@ -0,0 +1,9 @@
+export const FETCH_GOOGLE = 'FETCH_GOOGLE'
+
+export function fetchGoogle(google) {
+ console.log("fetching")
+ return{
+ type:FETCH_GOOGLE,
+ payload: google
+ }
+}
diff --git a/client/components/ArtGallery.js b/client/components/ArtGallery.js
index 53b0753..8fa7ef8 100644
--- a/client/components/ArtGallery.js
+++ b/client/components/ArtGallery.js
@@ -6,22 +6,29 @@ import * as art from '../models/art'
export default class App extends React.Component {
constructor(props) {
super(props);
-
this.state = {
tempCollection: [],
- artCollection: []
+ artCollection: [],
+ hipCollection: []
}
}
componentWillMount() {
- this.update()
+ if(true){
+ this.update()
+ }
}
+
update() {
+ console.log("params",this.props.params)
this.fetchArt(this.props.params.artistName)
.then(() => {
- this.getLikes()
+ this.getLikes()
+ this.getTrash()
+ this.getHipster()
})
}
+
signUp(userData) {
auth.signUp(userData)
}
@@ -30,14 +37,16 @@ export default class App extends React.Component {
}
fetchArt(artist) {
+ console.log("hhhry")
return art.getArt()
.then((artwork) => {
if(artist) {
- this.setState({tempCollection: artwork.filter((art) => art['Artist Name'] == artist)})
+ this.setState({tempCollection: artwork.filter((art) => art['Artist Full Name'] == artist)})
}
else {
this.setState({tempCollection: artwork})
}
+ console.log("what!")
})
}
@@ -54,12 +63,40 @@ export default class App extends React.Component {
})
}
+ getTrash(){
+ var trashResults = [];
+ this.state.tempCollection.forEach((artWork) => {
+ art.getTrash(artWork._id)
+ .then((trashCount) => {
+ trashResults.push(Object.assign(artWork, {trashCount: trashCount.trashCount}))
+ if (trashResults.length === this.state.tempCollection.length) {
+ this.setState({trashCollection: trashResults})
+ }
+ })
+ })
+ }
+
+ getHipster(){
+ var hipResults = [];
+ this.state.tempCollection.forEach((artWork) => {
+ art.getHipster(artWork._id)
+ .then((userScore) => {
+ hipResults.push(Object.assign(artWork, {userScore: userScore.userScore}))
+ if(hipResults.length === this.state.tempCollection.length) {
+ this.setState({hipCollection: hipResults})
+ }
+ })
+ })
+ }
+
+
render(){
+
return (
)
}
diff --git a/client/components/ArtMap.js b/client/components/ArtMap.js
new file mode 100644
index 0000000..20f9a59
--- /dev/null
+++ b/client/components/ArtMap.js
@@ -0,0 +1,87 @@
+import React from 'react'
+import {Link} from 'react-router'
+import NavBar from './NavBar'
+import * as auth from '../models/auth'
+import * as art from '../models/art'
+import GoogleMap from 'google-map-react';
+import TheMap from './theMap'
+
+
+
+export default class ArtistMap extends React.Component {
+
+constructor() {
+ super()
+ this.state = {
+ artists: [],
+ artistLat:[],
+ ArtName:[],
+ ArtLocation:[],
+ ArtTitle:[],
+ ArtistName:[],
+ ArtImage:[],
+ ArtWeb:[]
+ }
+
+ }
+
+componentDidMount() {
+ art.getArt()
+ .then((res) => {
+ this.setState({artists: res},(next)=>{
+ console.log("artists",this.state.artists)
+ var ArtName = this.state.ArtName.slice();
+ var ArtLocation = this.state.ArtLocation.slice();
+ var ArtTitle = this.state.ArtTitle.slice();
+ var ArtistName = this.state.ArtistName.slice();
+ var ArtImage = this.state.ArtImage.slice();
+ var ArtWeb = this.state.ArtWeb.slice();
+
+ var latLong = this.state.artists.map(artist =>{
+ ArtName.push(artist['Art Location Name']);
+ ArtLocation.push(artist['Art Location Street Address'])
+ ArtTitle.push(artist['Art Title'])
+ ArtistName.push(artist['Artist Full Name'])
+ ArtImage.push(artist['Images'])
+ ArtWeb.push(artist['Web Detail Page'])
+ //console.log("what",artTitle)
+
+ var stillNotFormatted = artist.Location.split('(')[1]
+ var slicedInfo = stillNotFormatted.slice(0,stillNotFormatted.length-1)
+ var lat = Number(slicedInfo.split(',')[0])
+ var lon = Number(slicedInfo.split(',')[1])
+ var latLon = {lat:lat,lng:lon}
+ return latLon
+ })
+ this.setState({ArtName})
+ this.setState({ArtLocation})
+ this.setState({ArtTitle})
+ this.setState({ArtistName})
+ this.setState({ArtImage})
+ this.setState({ArtWeb},function(){
+ // console.log("here",this.state.artName)
+ // console.log("ok",this.state.ArtTitle)
+ // console.log("here",this.state.artWeb)
+ // console.log("ok",this.state.artistName)
+ })
+
+ this.setState({artistLat:latLong})
+
+ })
+
+
+ })
+ }
+
+ render() {
+ return (
+
+
+
Artist List
+ {this.state.artistLat.length>0?:null}
+
+
+ )
+ }
+
+ }
diff --git a/client/components/ArtWindow.js b/client/components/ArtWindow.js
index bc4fb77..c13867b 100644
--- a/client/components/ArtWindow.js
+++ b/client/components/ArtWindow.js
@@ -3,12 +3,22 @@ import {ModalContainer, ModalDialog} from 'react-modal-dialog';
import ReactSpinner from 'react-spinjs';
import SearchInput, {createFilter} from 'react-search-input'
import NavBar from './NavBar'
+import Filter from './Filter'
import Slider from 'react-slick'
import * as auth from '../models/auth'
import * as art from '../models/art'
+import AMap from './googleMapTrial'
+
+
+
+
+var trashClass = "displayInline";
+
+
+const KEYS_TO_FILTERS = ['Artist Full Name', 'Art Title', 'Art Location Zip', 'Art Location Name']
+
-const KEYS_TO_FILTERS = ['Artist Name', 'Art Title']
export default class ArtGallery extends React.Component {
constructor(props) {
@@ -16,9 +26,12 @@ export default class ArtGallery extends React.Component {
this.state = {
showInfo: false,
- searchTerm: ''
+ searchTerm: [''],
+
}
+
}
+
parseImageUrl(imgUrl) {
imgUrl = imgUrl.split(';')
return imgUrl.filter((x) => x !== '')
@@ -28,24 +41,54 @@ export default class ArtGallery extends React.Component {
this.setState({currentArt: art})
}
closeInfo() {
+ console.log("what")
this.setState({showInfo: false});
}
searchUpdated (term) {
- this.setState({searchTerm: term})
+ var words = this.state.searchTerm;
+ console.log('what the fuck is this', this)
+ console.log('what is happening', words)
+ contacts.unshift(term);
+ console.log('is this updated?????', words[0])
}
+
updateCurrent(likeCount) {
this.setState({currentArt: Object.assign(this.state.currentArt, {likeCount: likeCount.likeCount})})
+ console.log("here")
+ }
+ updateCurrentTrash(trashCount) {
+ this.setState({currentArt: Object.assign(this.state.currentArt, {trashCount: trashCount.trashCount})})
+ console.log("there")
+ }
+ updateUserScore(userScore) {
+ this.setState({currentArt: Object.assign(this.state.currentArt, {userScore: userScore.userScore})})
+ console.log("where")
+ }
+
+
+ addToSearchTerm(contact) {
+ var contacts = this.searchTerm;
+ console.log(this)
+ console.log(contacts)
+ contacts.unshift(contact);
+ console.log(contacts[0])
+
}
render() {
- const filteredArt = this.props.gallery.filter(createFilter(this.state.searchTerm, KEYS_TO_FILTERS))
+
+ const filteredArt = this.props.gallery.filter(createFilter(this.state.searchTerm[0], KEYS_TO_FILTERS))
+ {console.log('DA FUCK IS THIS', this.props)}
+
+
return (
{/*If the gallery state is not populated, show the loading div. Else diaplay gallery*/}
- {!this.props.gallery[0] ?
+ {!this.props.gallery[0]
+ ?
-
Drawing pictures...
-
+
Finding your 'art'
+
:
@@ -54,7 +97,10 @@ export default class ArtGallery extends React.Component {
{this.state.showInfo ?
-
+
: null}
{filteredArt.map((art) => {
return (
@@ -65,17 +111,24 @@ export default class ArtGallery extends React.Component {
})}
}
+
+
+ {
}
+
+
)
}
}
//Create the info modal
class Info extends React.Component {
+
constructor() {
super()
this.state = {
userFavs: [],
- userId: null
+ userId: null,
+ // numRed:this.props..userScore
}
}
componentWillMount() {
@@ -96,6 +149,30 @@ class Info extends React.Component {
this.setState({userId: res})
})
}
+
+ buttonClick (event){
+ var userScore = event.target.value;
+ this.setState({numRed:userScore})
+ console.log('buttonClick', this.props.currentArt.userScore)
+
+ // () => auth.hipsterScore(this.props.currentArt._id)
+ // .then((x) => {
+ // return art.getHipster(this.props.currentArt._id)
+ // })
+ // .then((userScore) => {
+ // this.props.updateUserScore(userScore)
+ // })
+ }
+ makeRed(userScore){
+ for(var i=1;i<=userScore;i++){
+ var redButton = 'button'+i
+ this.setState({[redButton]:'btn btn-danger'})
+ }
+ for(var j = Number(userScore)+1 ;j<=5; j++){
+ var redButton = 'button'+j
+ this.setState({[redButton]:'btn'})
+ }
+ }
//The info modal that pops up with the props currentArt set as the object of the work of art you clicked on
render() {
let images = this.props.parseImageUrl(this.props.currentArt.Images);
@@ -112,30 +189,42 @@ class Info extends React.Component {
- {this.props.currentArt['Art Title']}
- By: {this.props.currentArt['Artist Name']}
+
+ {this.props.currentArt['Art Title']}
+
+
By: {this.props.currentArt['Artist Full Name']}
Location: {this.props.currentArt['Art Location Name']}
+
Likes: {this.props.currentArt.likeCount.length}
+
+
Not Art: {this.props.currentArt.trashCount.length}
+
Hipster Scale: {this.props.currentArt.userScore.length}
+
+
+
+
{/* Check if logged in (document.cookie?), if true display Like and Favorite button */}
{document.cookie ?
-
+ {(this.props.currentArt.trashCount.includes(this.state.userId)) ? '' :
+
+ }
+ {(this.props.currentArt.likeCount.includes(this.state.userId)) ? '' :
+
+ }
+
Peace be the Journey:
+
+
+
+
+
+
+
+
+
+
+
+
+
: ''}
diff --git a/client/components/ArtistPage.js b/client/components/ArtistPage.js
index 517230a..ff7c92a 100644
--- a/client/components/ArtistPage.js
+++ b/client/components/ArtistPage.js
@@ -18,7 +18,7 @@ export default class ArtistPage extends React.Component {
art.getArt()
.then((artwork) => {
if(artist) {
- this.setState({art: artwork.filter((art) => art['Artist Name'] == artist)})
+ this.setState({art: artwork.filter((art) => art['Artist Full Name'] == artist)})
}
else {
this.setState({art: artwork})
diff --git a/client/components/Artists.js b/client/components/Artists.js
index 4c7865d..7b857c2 100644
--- a/client/components/Artists.js
+++ b/client/components/Artists.js
@@ -18,10 +18,11 @@ export default class Artists extends React.Component {
componentWillMount() {
art.getArt()
.then((res) => {
- this.setState({artists: res.map((obj) => obj['Artist Name']).filter(this.onlyUnique)})
+ this.setState({artists: res.map((obj) => obj['Artist Full Name']).filter(this.onlyUnique)})
})
}
render() {
+ console.log("hhhh")
return (
diff --git a/client/components/Filter.js b/client/components/Filter.js
new file mode 100644
index 0000000..f97e4bc
--- /dev/null
+++ b/client/components/Filter.js
@@ -0,0 +1,96 @@
+import React from 'react'
+import {Link} from 'react-router'
+import {ModalContainer, ModalDialog} from 'react-modal-dialog';
+import ReactSpinner from 'react-spinjs';
+import ArtWindow from './ArtWindow';
+
+import * as auth from '../models/auth'
+
+export default class Filter extends React.Component {
+
+ constructor() {
+ super()
+
+ this.state = {
+ isLoading: false,
+ showError: false,
+ artists: null,
+ locations: null,
+ zip: null,
+ }
+
+ }
+
+ load() {
+ this.setState({isLoading: true});
+ setTimeout(() => {
+ this.setState({isLoading: false});
+ }, 1500);
+ }
+
+ render() {
+
+ var artList;
+ if(this.props.gallery){
+ artList = this.props.gallery;
+ }
+
+ return
+ {this.state.isLoading ?
+
+ :
+
+
+
+ }
+
+ ;
+ }
+}
+
diff --git a/client/components/HomePage.js b/client/components/HomePage.js
index 388662b..fb4c9e1 100644
--- a/client/components/HomePage.js
+++ b/client/components/HomePage.js
@@ -1,24 +1,36 @@
import React, {PropTypes} from 'react';
import {Link} from 'react-router';
+import NavBar from './NavBar'
export default class HomePage extends React.Component {
//The homepage component with links to gallery and artists page on the two buttons.
render() {
+
return (
-
+
+
-
AUSTIN ART
+
+
+
AUSTIN ART
GALLERY
+
+
ARTISTS
+
-
+
)
+
}
+ grabStuff(){
+ console.log("hellos")
+ }
}
diff --git a/client/components/Map.js b/client/components/Map.js
new file mode 100644
index 0000000..215e303
--- /dev/null
+++ b/client/components/Map.js
@@ -0,0 +1,43 @@
+import React from 'react'
+import {GoogleApiWrapper} from 'google-maps-react'
+export class Map extends React.Component {
+
+ componentDidUpdate(prevProps, prevState) {
+ if (prevProps.google !== this.props.google) {
+ this.loadMap();
+ }
+ }
+ componentDidMount() {
+ this.loadMap();
+ }
+
+ loadMap() {
+ if (this.props && this.props.google) {
+ // google is available
+ const {google} = this.props;
+ const maps = google.maps;
+
+ const mapRef = this.refs.map;
+ const node = ReactDOM.findDOMNode(mapRef);
+
+ let zoom = 14;
+ let lat = 37.774929;
+ let lng = -122.419416;
+ const center = new maps.LatLng(lat, lng);
+ const mapConfig = Object.assign({}, {
+ center: center,
+ zoom: zoom
+ })
+ this.map = new maps.Map(node, mapConfig);
+ }
+ }
+
+ render() {
+ console.log("heyyyy!")
+ return(
+
+
Loading map
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/client/components/NavBar.js b/client/components/NavBar.js
index 62ffaa9..94950e6 100644
--- a/client/components/NavBar.js
+++ b/client/components/NavBar.js
@@ -2,6 +2,8 @@ import React from 'react'
import {Link} from 'react-router'
import {ModalContainer, ModalDialog} from 'react-modal-dialog';
import ReactSpinner from 'react-spinjs';
+import ArtWindow from './ArtWindow'
+import Filter from './Filter'
import * as auth from '../models/auth'
@@ -11,6 +13,7 @@ export default class NavBar extends React.Component {
this.state = {
showLogin: false,
showSignup: false,
+ showFilter: false,
showError: false,
loggedIn: document.cookie,
username: null
@@ -39,6 +42,12 @@ export default class NavBar extends React.Component {
this.setState({loggedIn: bool})
this.setState({showSignup: false});
}
+ openFilter() {
+ this.setState({showFilter: true});
+ }
+ closeFilter(bool) {
+ this.setState({showFilter: false});
+ }
logout(name) {
document.cookie = 'sessionId' + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
this.setState({loggedIn: false})
@@ -58,27 +67,34 @@ export default class NavBar extends React.Component {
//Render the navbar
render() {
+
+
return(
-
+
-
{/* Populate the navbar items. Use from react router to add links to different views. */}
+
- HOME
- ARTISTS
- GALLERY
+ - MAP
{this.state.loggedIn ? - FAVORITES
: null}
+
-
ACCOUNT
-
- - {this.drawUsername()}
+ {this.state.loggedIn ? - {this.drawUsername()}
: null}
{this.state.showSignup ?
@@ -86,6 +102,13 @@ export default class NavBar extends React.Component {
{this.state.showLogin ?
: null}
+ {this.state.showFilter ?
+
+
+
+
+
+ : null}
)
}
@@ -176,6 +199,7 @@ class SignUpModal extends React.Component {
e.preventDefault();
auth.signUp({username: this.state.username, password: this.state.password})
.then((x) => {
+ console.log("xxxxxxxx", x)
if(x === 'Success') {
this.setState({showError: false})
this.props.onClose(true)
@@ -184,6 +208,10 @@ class SignUpModal extends React.Component {
this.setState({showError: x.statusText})
}
})
+ // .catch(err => {
+ // console.log("ERRRRRR", err)
+ // this.setState({showError: err})
+ // })
this.load.call(this);
}}>
SignUp
@@ -198,4 +226,4 @@ class SignUpModal extends React.Component {
}
;
}
-}
\ No newline at end of file
+}
diff --git a/client/components/googleMapTrial.js b/client/components/googleMapTrial.js
new file mode 100644
index 0000000..df5e62f
--- /dev/null
+++ b/client/components/googleMapTrial.js
@@ -0,0 +1,103 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import {Gmaps, Marker, InfoWindow, Circle} from 'react-gmaps';
+
+
+export default class AMap extends React.Component {
+
+constructor(props) {
+ super(props)
+
+ this.state = {
+ lat:Number(this.props.location[0]),
+ lng: Number(this.props.location[1]),
+ location:{}
+ }
+
+ console.log("Location",this.props.location)
+ navigator.geolocation.getCurrentPosition(suc.bind(this),fail);
+ function suc(position){
+ var latitude = position.coords.latitude;
+ var longitude = position.coords.longitude;
+ this.setState({location:{lat:latitude,lng:longitude}})
+ }
+ function fail(){
+ console.log("booo!")
+ }
+ }
+
+
+
+ onMapCreated(map) {
+ map.setOptions({
+
+
+ });
+ }
+
+ onDragEnd(e) {
+ console.log('onDragEnd', e);
+ }
+
+ onCloseClick() {
+ console.log('onCloseClick');
+ }
+
+ onClick(e) {
+ console.log('onClick', e);
+ }
+
+
+
+ render() {
+ console.log(this.state.lat,this.state.lng,this.state.location.lat,this.state.location.lng)
+ var R = 6371000
+ var lat1 = this.state.lat*Math.PI/180
+ var lng1 = this.state.lng*Math.PI/180
+ var lat2 =this.state.location.lat*Math.PI/180
+ var lng2 = this.state.location.lng*Math.PI/180
+ var deltaLat = lat1-lat2
+ var deltaLng = lng1-lng2
+ var a = Math.sin(deltaLat/2)*Math.sin(deltaLat/2)+Math.cos(lat1)*Math.cos(lat2)*Math.sin(deltaLng/2)*Math.sin(deltaLng/2);
+ var c = 2*Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
+ var d = R*c
+ console.log("D",lat1,lat2,lng1,lng2,deltaLat,deltaLng,a,c,d)
+
+ var lat = this.state.lat
+ console.log("work?",lat*Math.PI/180)
+ return (
+ 10000?11:(d>6000?12:(d<2500?16:14))}
+ loadingMessage={'Be happy'}
+ params={{v: '3.exp', key: 'AIzaSyBBJCIum7iZSy8nRDjJhSjFjRx4nrGZiPU'}}
+ onMapCreated={this.onMapCreated}>
+
+
+
+
+
+
+
+ );
+ }
+
+};
\ No newline at end of file
diff --git a/client/components/theMap.js b/client/components/theMap.js
new file mode 100644
index 0000000..3410255
--- /dev/null
+++ b/client/components/theMap.js
@@ -0,0 +1,125 @@
+import React from 'react'
+//import Map from './Map'
+//import {GoogleApiWrapper} from 'GoogleMapsReactComponent'
+import {GoogleApiWrapper, Map, Marker, InfoWindow} from 'google-maps-react'
+import {connect} from 'react-redux'
+import { bindActionCreators} from 'redux';
+import {fetchGoogle} from '../actions/index';
+
+class TheMap extends React.Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ artistLocations: [],
+ activeMarker:{},
+ showingInfoWindow:false,
+ selectedPlace:{},
+ location:{},
+ }
+ navigator.geolocation.getCurrentPosition(suc.bind(this),fail);
+ function suc(position){
+ var latitude = position.coords.latitude;
+ var longitude = position.coords.longitude;
+ this.setState({location:{lat:latitude,lng:longitude}})
+ }
+ function fail(){
+ console.log("booo!")
+ }
+
+ }
+
+
+
+onMarkerClick(props, marker, e){
+ console.log("hey now",marker)
+ this.setState({
+ selectedPlace: props,
+ activeMarker: marker,
+ showingInfoWindow: true
+ });
+
+}
+onMapClicked(props){
+ console.log("OH MY")
+ if (this.state.showingInfoWindow) {
+ this.setState({
+ showingInfoWindow: false,
+ activeMarker: null
+ })
+ }
+}
+
+ render() {
+ const style = {
+ width: '100vw',
+ height: '95vh'
+ }
+ console.log("active",this.state.activeMarker)
+ var positions = this.props.artists;
+ console.log(this.props.artists[0])
+ console.log('SO',this.state.location)
+ console.log("thiss",this.props.google)
+ if(this.props.google){
+ this.props.fetchGoogle(this.props.google)
+ }
+ console.log("MONKEY",this.props.googley)
+ return (
+
+ {this.state.location.lat?
:null}
+
+
+ )
+ }
+}
+
+// export default GoogleApiWrapper({
+// apiKey: 'AIzaSyBBJCIum7iZSy8nRDjJhSjFjRx4nrGZiPU'
+// })(TheMap)
+
+ function mapDispatchToProps(dispatch) { //Think of mapDispatchToProps as this is how you SEND stuff to the store
+ return bindActionCreators({
+ fetchGoogle,
+ }, dispatch)
+ }
+
+ function mapStateToProps(state) { //this of mapStateToProps as this is how you GET stuff from the store
+ return {
+ googley: state.google,
+
+ }
+ }
+
+ export default connect(mapStateToProps, mapDispatchToProps)(GoogleApiWrapper({
+ apiKey: 'AIzaSyBBJCIum7iZSy8nRDjJhSjFjRx4nrGZiPU'
+})(TheMap))
\ No newline at end of file
diff --git a/client/main.js b/client/main.js
index e5fa666..6200935 100644
--- a/client/main.js
+++ b/client/main.js
@@ -6,19 +6,25 @@ import Home from './components/HomePage'
import Gallery from './components/ArtGallery'
import ArtistPage from './components/ArtistPage'
import FavsPage from './components/FavsPage'
+import ArtistMap from './components/ArtMap'
+import AMap from './components/googleMapTrial'
+import { Provider } from 'react-redux';
+import { createStore, applyMiddleware } from 'redux';
+import reducers from './reducers';
-
-
-
-//Create the route configuration
+const createStoreWithMiddleware = applyMiddleware()(createStore);
+//Create the route configuration test
render((
+
-
+
+
+
), document.getElementById('app'))
diff --git a/client/models/art.js b/client/models/art.js
index 5034dcc..4007efd 100644
--- a/client/models/art.js
+++ b/client/models/art.js
@@ -1,6 +1,7 @@
import fetch from 'isomorphic-fetch';
export function getArt (){
+ console.log('hello')
let obj = {
method: 'GET'
};
@@ -19,3 +20,26 @@ export function getLikes(artId) {
return artwork.json()
})
}
+
+export function getTrash(artId) {
+ let obj = {
+ method: 'GET'
+ };
+ return fetch(`/trash/${artId}`, obj)
+ .then((artwork) => {
+ return artwork.json()
+ })
+}
+
+export function getHipster(artId){
+ let obj = {
+ method: 'GET'
+ };
+ return fetch(`/hipster/${artId}`, obj)
+ .then((artwork) => {
+ return artwork.json()
+ })
+ .catch((error) => {
+ console.log('art error', error)
+ })
+}
diff --git a/client/models/auth.js b/client/models/auth.js
index f1e3aa3..01f2538 100644
--- a/client/models/auth.js
+++ b/client/models/auth.js
@@ -11,12 +11,18 @@ export function signUp(userData) {
}
return fetch(`/signUp`, obj)
.then(function(data){
+ console.log("DATATATATATA", data)
if(data.status < 400) {
return data.json().then((data) => {
+ console.log("INSIDE OF THIS", data)
document.cookie = "sessionId=" + data + ";path=/"
return "Success"
})
- } else return data
+ }
+ else{
+ console.log("elseelse", data)
+ return data
+ }
})
}
@@ -31,8 +37,10 @@ export function login(userData) {
}
return fetch(`/login`, obj)
.then(function(data){
+ console.log("datalogin", data)
if(data.status < 400) {
return data.json().then((data) => {
+ console.log("logIN", data)
document.cookie = "sessionId=" + data + ";path=/"
return "Success"
})
@@ -54,6 +62,37 @@ export function likePhoto(artId) {
})
}
+export function trashPhoto(artId) {
+ let obj = {
+ method: "POST",
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({cookie: document.cookie})
+ }
+ return fetch(`/trash/${artId}`, obj)
+ .then(function(data){
+ return data.json()
+ })
+}
+
+export function hipsterScore(artId) {
+ let obj = {
+ method: "POST",
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({cookie: document.cookie})
+ }
+ return fetch(`/hipster/${artId}`, obj)
+ .then(function(data){
+ return data.json()
+ })
+ .catch(function(error){
+ console.log('auth error', error)
+ })
+}
+
export function favoritePhoto(artId) {
let obj = {
method: "POST",
@@ -110,3 +149,19 @@ return fetch(`/username`, obj)
})
}
+export function fetchFBData(){
+ let obj = {
+ method: 'GET',
+ headers:{
+ 'Content-Type': 'application/json',
+ 'cookieheader': document.cookie
+ }
+ }
+ return fetch(`/facebookLogin/Callback`, obj)
+ .then(function(resp){
+ console.log("resp", resp)
+ console.log("Resp.json()",resp.json())
+ return resp.json()
+ })
+}
+
diff --git a/client/public/css/style.css b/client/public/css/style.css
index b4781c2..d421e7e 100644
--- a/client/public/css/style.css
+++ b/client/public/css/style.css
@@ -6,22 +6,26 @@
.slideContainer {
margin: 0 auto;
padding: 40px;
- width: 800px;
+ width: 600px;
height: 1000px
color: #333;
- background: black;
+/* background: black;*/
}
-.loadingDiv {
- background-color: lightgrey;
+
+.loadingDiv {
+ text-align: -webkit-center;
+/* background-color: lightgrey;
width: 300px;
border: 10px solid black;
padding: 25px;
- margin: auto;
+ margin: auto;*/
}
-.loadingDiv p {
+
+/*.loadingDiv p {
padding-top: 50px;
text-align: -webkit-center;
-}
+}*/
+
.closeButton--jss-0-1 {
display: none !important;
}
@@ -29,15 +33,15 @@
color: red;
}
.artImage {
- height: 345px;
- width: 345px;
+ height: 250px;
+ width: 250px;
border-radius: 100%;
display: block;
margin: 0 auto;
}
.artGallery {
--moz-column-count: 3;
--webkit-column-count: 3;
+-moz-column-count: 4;
+-webkit-column-count: 4;
}
.search-input {
margin: 0 100px 10px 100px;
@@ -48,11 +52,10 @@
text-align: center;
}
.artwork{
-
display: block;
margin: 0 auto;
- height: 360px;
- width: 360px;
+ height: 275px;
+ width: 275px;
}
.artTitle{
text-align: center;
@@ -143,7 +146,7 @@ p {
/* home section styles
/* ========================================== */
#home {
- background: url('../images/austin-texas-wallpaper-1.jpg') 50% 0 repeat-y fixed;
+ background: url('http://4.bp.blogspot.com/-uP2IZK4vPFc/UxlnO8hTk0I/AAAAAAAAASo/mNoQ9NuwIgM/s1600/IMG_1070.JPG') 50% 0 repeat-y fixed;
-webkit-background-size: cover;
background-size: cover;
background-position: center center;
@@ -159,38 +162,68 @@ p {
text-align: center;
}
-#home h1 {
- color: white;
-}
-#home .btn-danger {
- background: black !important;
- margin-right: 20px;
+#home p {
+ color: white;
+ /* font-family: Arial, Helvetica, sans-serif;*/
+ font-size: 125px;
}
-#home .btn-danger:hover {
- background: #ffa400 !important;
+/*#home span {
+ background-color: rgba(10, 128, 128, .5);
}
-
+*/
#home .btn {
- background: #4C8DF8;
+ background: transparent;
border-color: transparent;
color: #ffffff;
- font-size: 12px;
- font-weight: bold;
+ font-size: 33px;
+ /*font-weight: bold;*/
padding: 14px 52px;
margin-top: 40px;
transition: all 0.4s ease-in-out;
}
+/*#home .btn-danger {
+ background: black !important;
+ margin-right: 20px;
+}
+
+#home .btn-danger:hover {
+ background: #ffa400 !important;
+}
+
#home .btn:hover {
background: #ffa400;
-}
+}*/
/* Navbar styles */
/* ========================================= */
+
.usernameSpan {
margin: 30px;
position: relative;
top: 11.5px;
}
+
+/* Home Page Borders */
+/* ========================================= */
+/*#home .top, .bottom, .left, .right {
+ background: teal;
+ position: fixed;
+ opacity: 0.5;
+ }
+
+#home .left, .right {
+ top: 0; bottom: 0;
+ width: 15px;
+ }
+ .left { left: 0; }
+ .right { right: 0; }
+
+#home .top, .bottom {
+ left: 0; right: 0;
+ height: 15px;
+ }
+ .top { top: 0; }
+ .bottom { bottom: 0; }*/
\ No newline at end of file
diff --git a/client/public/index.html b/client/public/index.html
index ad35b08..ac0f7d3 100644
--- a/client/public/index.html
+++ b/client/public/index.html
@@ -1,10 +1,10 @@
- Austin Art
+ LEGACY: Austin Art
-
+
@@ -14,7 +14,7 @@
diff --git a/client/reducers/index.js b/client/reducers/index.js
new file mode 100644
index 0000000..234dc9e
--- /dev/null
+++ b/client/reducers/index.js
@@ -0,0 +1,11 @@
+import { combineReducers } from 'redux';
+import GoogleReducer from './reducer_google'
+
+//So in the regular code, your component created an action which went to actions.js. That then goes to a specific reducer. All the reducers are then bundled up here
+//and sent to the store.
+const rootReducer = combineReducers({
+ google: GoogleReducer
+});
+
+export default rootReducer;
+
diff --git a/client/reducers/reducer_google.js b/client/reducers/reducer_google.js
new file mode 100644
index 0000000..b5cd88e
--- /dev/null
+++ b/client/reducers/reducer_google.js
@@ -0,0 +1,15 @@
+import {FETCH_GOOGLE} from '../actions/index'
+
+const INITIAL_STATE = {all: [], post: null};
+
+
+export default function(state = INITIAL_STATE, action){
+ switch(action.type){
+ case FETCH_GOOGLE:
+ return action.payload
+
+ default:
+ return state;
+
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index cdac853..1f6db7e 100644
--- a/package.json
+++ b/package.json
@@ -25,20 +25,38 @@
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.15.2",
"browserify-middleware": "^7.0.0",
+ "connect-flash": "^0.1.1",
"express": "^4.13.4",
+ "express-session": "^1.14.0",
+ "google-map-react": "^0.16.0",
+ "google-maps-react": "^1.0.16",
"isomorphic-fetch": "^2.2.1",
"node-uuid": "^1.4.7",
"nodemon": "^1.9.2",
+ "passport": "^0.3.2",
+ "passport-facebook": "^2.1.1",
+ "passport-instagram": "^1.0.0",
+ "passport-local": "^1.0.0",
"path": "^0.12.7",
"promised-mongo": "github:makersquare/promised-mongo",
"react": "^15.1.0",
"react-bootstrap": "^0.29.5",
"react-dom": "^15.1.0",
+ "react-gmaps": "^1.5.0",
+ "react-google-maps": "^4.11.0",
"react-modal-dialog": "^3.0.1",
+ "react-redux": "^4.4.5",
"react-router": "^2.5.2",
"react-search-input": "^0.10.1",
"react-slick": "^0.12.2",
"react-spinjs": "^3.0.0",
+ "redux": "^3.5.2",
"uuid-js": "^0.7.5"
+ },
+ "babel": {
+ "presets": [
+ "es2015",
+ "react"
+ ]
}
}
diff --git a/server/db.js b/server/db.js
index 592c945..10c3bb0 100644
--- a/server/db.js
+++ b/server/db.js
@@ -1,6 +1,10 @@
var pmongo = require('promised-mongo');
-var uri = 'mongodb://fullstackwizards:pancakes@ds015995.mlab.com:15995/austinart';
+
+
+var uri = 'mongodb://jad:carson@ds023485.mlab.com:23485/austin_art';
+
+
var db = pmongo(uri, {
authMechanism: 'ScramSHA1'
diff --git a/server/main.js b/server/main.js
index 0be67b3..d5d45a4 100644
--- a/server/main.js
+++ b/server/main.js
@@ -2,11 +2,17 @@ var express = require('express');
var path = require('path');
var browserify = require("browserify-middleware");
var bodyParser = require('body-parser');
+var passport = require("passport");
+var LocalStrategy = require('passport-local').Strategy;
+var InstagramStrategy = require('passport-instagram').Strategy;
var Utils = require(path.join(__dirname, './utils.js'));
var db = require(path.join(__dirname, './db.js'));
var app = express();
+var session = require('express-session')
+
+require('./passport')(passport);
app.use(express.static(path.join(__dirname, "../client/public")));
app.use(bodyParser.json());
@@ -17,27 +23,62 @@ browserify(path.join(__dirname, '../client/main.js'), {
})
);
+
+app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
+
+
+app.use(passport.initialize());
+app.use(passport.session());
+
+
+app.get('/facebookLogin',
+ passport.authenticate('facebook'));
+
+
+app.get('/facebookLogin/Callback',
+ passport.authenticate('facebook', { failureRedirect: '/' }),
+ function(req, res) {
+
+ console.log("REQQQQQQQ",req.user)
+ console.log("RESSSSSSS",res.user)
+ res.send(req.user)
+ res.redirect('/#/gallery');
+ });
+
+
// client asking for art data
app.get('/art', function(req,res) {
//retrieve all art from db
- db.collection('art').find()
+ db.art.find()
.then((art) => {
res.send(art)
})
})
+app.post('/insertArt',function(req,res){
+ db.collection('art').insert(req.body).then(function(value){
+ db.collection('art').find().then(function(value){
+ res.send(value)
+ })
+ })
+
+})
-app.post('/signUp', function(req, res) {
- var username = req.body.username;
+app.post('/signUp',passport.authenticate('local-signup'),function(req, res) {
+ console.log("IN MAIN NOW")
+ var username = req.body.username;
var password = req.body.password;
-
+ console.log("req",req.sessionID)
+ // console.log("res",res.body)
db.collection('users').find({username: username})
.then((user) => {
- if(user[0]){
- res.statusMessage = "Username taken."
- res.status(400).end();
- } else {
+ // console.log("USERS MAIN",user)
+ // console.log("USERS[0]", user[0])
+ // if(user[0]){
+ // res.statusMessage = "Username taken."
+ // res.status(400).end();
+ // } else {
return Utils.hashPassword(password)
- }
+ // }
})
.then(function(hash){
return db.collection('users').insert({username: username, password: hash});
@@ -47,15 +88,19 @@ app.post('/signUp', function(req, res) {
return db.collection('sessions').insert({id: obj._id, sessionId: sessionId});
})
.then(function(obj){
+ console.log("SIGN UP SESSION",req.sessionID)
res.send(JSON.stringify(obj.sessionId));
})
})
+
// Logs in current user as long as username is in users collection and provided a valid password
-app.post('/login', function(req, res) {
+app.post('/login', passport.authenticate('local-login'),function(req, res) {
var username = req.body.username;
var password = req.body.password;
var userID;
+ console.log("REQID", req.sessionId)
+ console.log("REQID", req.sessionID)
db.collection('users')
.find({username: username})
.then((userObj) => {
@@ -77,6 +122,7 @@ app.post('/login', function(req, res) {
}
})
.then((userObj) => {
+ console.log("SIGN IN SESSION",userObj.sessionId)
res.send(JSON.stringify(userObj.sessionId))
})
})
@@ -220,6 +266,105 @@ app.post('/like/:id', function(req, res){
}
})
+app.post('/trash/:id', function(req, res){
+ var artId = req.params.id;
+ var sessionId = req.body.cookie.substring(10);
+ var userId;
+
+ if(!sessionId){
+ res.sendStatus(401)
+ } else {
+ db.collection('sessions').find({ sessionId: sessionId })
+ .then((users) => {
+ // Get user id from session
+ userId = users[0].id;
+ return db.collection('users').find({ _id: userId })
+ })
+ .then((users) => {
+ // Check if user exists
+ if(users[0]){
+ return db.collection('trash').find({ userId: userId, artId: artId })
+ } else {
+ // User doesn't exist, send back -bad request-
+ res.sendStatus(400)
+ }
+ })
+ .then((trash) => {
+ // Check if user has already liked the art
+ if(trash[0]){
+ // if so then the user will unlike the art
+ return db.collection('trash').remove({ userId: userId, artId: artId })
+ } else {
+ // if not then the user will like the art
+ return db.collection('trash').insert({ userId: userId, artId: artId })
+ }
+
+ })
+ .then((result) => {
+ res.send({ "Status": "Success" })
+ })
+ }
+})
+
+app.post('/hipster/:id', function(req, res){
+ var artId = req.params.id;
+ var sessionId = req.body.cookie.substring(10);
+ var userId;
+
+ if(!sessionId){
+ res.sendStatus(401)
+ } else {
+ db.collection('sessions').find({ sessionId: sessionId })
+ .then((users) => {
+ // Get user id from session
+ userId = users[0].id;
+ return db.collection('users').find({ _id: userId })
+ })
+ .then((users) => {
+ // Check if user exists
+ if(users[0]){
+ return db.collection('hipster').find({ userId: userId, artId: artId })
+ } else {
+ // User doesn't exist, send back -bad request-
+ res.sendStatus(400)
+ }
+ })
+ .then((userScore) => {
+ return db.collection('hipster').insert({ userId: userId, artId: artId, userScore:userScore })
+ })
+ .then((result) => {
+ res.send({ "Status": "Success" })
+ })
+ .catch((error) => {console.log('main error', error)})
+ }
+})
+
+app.get('/trash/:id', function(req, res){
+ var artId = req.params.id;
+
+ if(!artId){
+ res.status(400).send({"Error": "No art id... Come on now"})
+ } else {
+ db.collection("trash").find({ artId: artId })
+ .then((trash) => {
+ res.send({ trashCount: trash.map((x) => x.userId) })
+ })
+ }
+})
+
+app.get('/hipster/:id', function(req, res){
+ var artId = req.params.id;
+
+ if(!artId){
+ res.status(400).send({"Error": "No art id... Come on now"})
+ } else {
+ db.collection("hipster").find({ artId: artId })
+ .then((userScore) => {
+ res.send({ userScore: userScore.map((x) => x.userId) })
+ })
+ }
+})
+
app.get('/likes/:id', function(req, res){
var artId = req.params.id;
@@ -233,6 +378,12 @@ app.get('/likes/:id', function(req, res){
}
})
+app.get('/instagramLogin', passport.authenticate('instagram'));
+
+app.get('/instagramLogin/Callback', passport.authenticate('instagram', {successRedirect: '/', failureRedirect: '/login'}), function(req,res) {
+ res.redirect('/gallery')
+})
+
// Run server on port 4040
var port = process.env.PORT || 4040;
diff --git a/server/passport.js b/server/passport.js
new file mode 100644
index 0000000..eda49ec
--- /dev/null
+++ b/server/passport.js
@@ -0,0 +1,214 @@
+var FACEBOOK_ID = '932055926922953';
+var FACEBOOK_CALLBACK_URL = 'http://localhost:4040/facebookLogin/Callback'
+var FACEBOOK_SECRET = 'c283a4b04e8635a09c8ac2d0ed071e30'
+var PROFILE_FIELDS = ['id', 'email', 'photos','gender', 'link', 'locale', 'name', 'timezone', 'updated_time', 'verified']
+var INSTAGRAM_ID = '11aeef855e224c23ab73786f79c3f1d1';
+var INSTAGRAM_CALLBACK_URL = 'http://localhost:4040/instagramLogin/Callback';
+var INSTAGRAM_SECRET = '11412943ed9a42cf994b54ec4ba28b3e';
+var passport = require("passport");
+var LocalStrategy = require('passport-local').Strategy;
+var FacebookStrategy = require('passport-facebook').Strategy;
+var InstagramStrategy = require('passport-instagram').Strategy;
+var path = require('path');
+var db = require(path.join(__dirname, './db.js'));
+var Utils = require(path.join(__dirname, './utils.js'));
+
+module.exports = function(passport){
+
+ passport.serializeUser(function(user, callback){
+ console.log("HEY THERE")
+ console.log("SUSERS", user)
+ callback(null, user.userID || user.facebookID || user || user.instagramID)
+ });
+
+ passport.deserializeUser(function(id,callback){
+ console.log("Decerael" , id)
+ findUserByID(id).then(function(value){
+ console.log("value", value)
+ if(value){
+ console.log("IFVALUE!!!!!!", value)
+ done(null, value);
+ }
+ else{
+ console.log("ELSE")
+ done('no session exists',value)
+ }
+ })
+ })
+
+ passport.use('local-signup', new LocalStrategy(
+ function(username,password,callback){
+ process.nextTick(function(){
+ console.log('Local', username, password, callback)
+ db.collection('users').find({username: username}).then((user) => {
+ console.log("user", user)
+ if(user.length > 0){
+ if(user[0].username){
+ return callback(null,false);
+ }
+ }
+ else {
+ console.log("ESEESE", password)
+ return Utils.hashPassword(password)
+ .then(function(hash) {
+ console.log("HASSSSHH", hash)
+ return db.collection('users').insert({username: username, password: hash})
+ })
+ .then(function(obj) {
+ var sessionId = Utils.createSessionId();
+ return db.collection('sessions').insert({id: obj._id, sessionId: sessionId});
+ })
+ .then(function(obj) {
+ console.log("OBJOBJOBJ", callback)
+ console.log('SIGNUP USERID SUCCESS', {userID:obj})
+ return callback(null, {userID:obj})
+ })
+ }
+ })
+ }
+ )
+ }
+ ))
+
+ passport.use('local-login', new LocalStrategy(
+ function(username, password, callback) {
+ console.log('LOCAL LOGIN', username, password, callback)
+ process.nextTick(function() {
+ db.collection('users').find({username: username}).then((user) => {
+ console.log('USERVALUE', user)
+ if(user.length > 0) {
+ Utils.comparePassword(user[0].password, password).then(val => {
+ if (val === true) {
+ console.log('CORRECT PASSWORD')
+ return callback(null, user[0]);
+ } else {
+ console.log('user exists, but wrong password')
+ return callback(null, false, flash('badPass', 'Incorrect password'));
+ }
+ })
+ .catch(val => {
+ console.log('Password incorrect', val);
+ return callback(null, false, flash('badPass', 'Incorrect password'));
+ })
+ } else {
+ console.log('User not found');
+ return callback(null, false, flash('noUser', 'Username not found'));
+ }
+ })
+ })
+ }
+ ))
+
+
+ passport.use(new FacebookStrategy({
+ clientID: FACEBOOK_ID,
+ clientSecret: FACEBOOK_SECRET,
+ callbackURL : FACEBOOK_CALLBACK_URL,
+ profileFields : PROFILE_FIELDS,
+ enableProof: true
+ },function(token,refreshToken,profile,done){
+ process.nextTick(function(){
+ console.log('profile',profile.id, profile[0])
+ // check if in users database
+ // return db.collection('FBusers').find({facebookID: profile.id}).then(function(uservalue){
+ // console.log("THIS VALUE1ST!!",userValue)
+ // if(userValue.length>0){
+ // console.log("VALUEINFBSTAR", userValue)
+ // return done(null, userValue) //already exists
+ // }
+ // else{
+ addFacebookUser(profile,token).then(function(userValue){
+ console.log('HASH',userValue)
+ return done(null,userValue)
+ })
+ })
+ // return done(null,profile)
+ //doesn't exist
+
+ }))
+
+ passport.use(new InstagramStrategy({
+ clientID: INSTAGRAM_ID,
+ clientSecret: INSTAGRAM_SECRET,
+ callbackURL: INSTAGRAM_CALLBACK_URL
+ },
+ function(token, refreshToken, profile, done) {
+ process.nextTick(function () {
+ db.collection('users').find({instagramID: profile.id}).then(user => {
+ if (user.length > 0) {
+ return done(null, user[0])
+ }
+ else {
+ addInstagramUser(profile, token).then(userVal => {
+ console.log('DONE', done);
+ console.log('USERVAL', userVal)
+ return done(null, userVal);
+ })
+ }
+ })
+ });
+ }))
+}
+// // })
+
+// // }
+// // ))
+// }
+ function addFacebookUser(user,token) {
+ console.log('USER',user, "token" ,token)
+ return db.collection('FBusers').insert({
+ facebookID: user.id,
+ facebookToken: token,
+ facebookPicture: user.photos[0],
+ facebookName: user.name
+
+
+ })
+ }
+
+function addInstagramUser(user, token) {
+ console.log('USER',user, 'TOKEN', token)
+
+ console.log('inside inserting IG user')
+ return db.collection('IGusers').insert({
+ instagramID: user.id,
+ instagramToken: token
+ })
+
+}
+
+
+
+// var findUserByID = function(ID) {
+// console.log("FINDUSERID", ID)
+// return db.collection('IGusers').find({
+// instagramID : ID
+// }).then(value => {
+// console.log('valueIDID',value)
+// if (value.length > 0) {
+// return value[0];
+// }
+// return false;
+// })
+// }
+ var findUserByID = function(ID) {
+ console.log("FINDUSERID", ID)
+ return (db.collection('FBusers').find({
+ facebookID : ID
+ }) || db.collection('IGusers').find({
+ instagramID : ID
+ })).then(function(value) {
+ console.log('valueIDID',value)
+ if (value.length > 0) {
+ return value[0];
+ }
+ return false;
+ })
+}
+
+//need to add a FB user to the database. Then i will be able to check for the id
+
+//need to fetch the picture and put it in the facebook login modal.
+
+ // }))
+// }