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..8068dd6 100644 --- a/client/components/ArtGallery.js +++ b/client/components/ArtGallery.js @@ -9,19 +9,27 @@ export default class App extends React.Component { 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.getTrash() + this.getHipster() }) } + signUp(userData) { auth.signUp(userData) } @@ -33,7 +41,7 @@ export default class App extends React.Component { 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}) @@ -54,12 +62,39 @@ 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..9646e23 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 !== '') @@ -31,21 +44,48 @@ export default class ArtGallery extends React.Component { 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})}) } + updateCurrentTrash(trashCount) { + this.setState({currentArt: Object.assign(this.state.currentArt, {trashCount: trashCount.trashCount})}) + } + updateUserScore(userScore) { + this.setState({currentArt: Object.assign(this.state.currentArt, {userScore: userScore.userScore})}) + } + + + 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.state.searchTerm)} + + 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 +94,10 @@ export default class ArtGallery extends React.Component {
{this.state.showInfo ? - + : null} {filteredArt.map((art) => { return ( @@ -65,6 +108,11 @@ export default class ArtGallery extends React.Component { })}
} + + + {} + +
) } @@ -75,7 +123,8 @@ class Info extends React.Component { super() this.state = { userFavs: [], - userId: null + userId: null, + // numRed:this.props..userScore } } componentWillMount() { @@ -96,8 +145,33 @@ 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); let settings = { dots: true, @@ -112,30 +186,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}

+
+ +
{images.map((x) =>
)}
+ {/* 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..14c2e6a 100644 --- a/client/components/Artists.js +++ b/client/components/Artists.js @@ -18,7 +18,7 @@ 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() { 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 ? + + : + +
{ + e.preventDefault(); + this.props.onClose(true); + this.load.call(this); + }}> +

Filter

+ +


+ +


+ +


+

+
+
+ } + +
; + } +} + 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..3825772 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,33 @@ 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.state.loggedIn ? : - Logout} + Logout} + Facebook
    • -
    • -
    • {this.drawUsername()}
    • + {this.state.loggedIn ?
    • {this.drawUsername()}
    • : null}
    {this.state.showSignup ? @@ -86,6 +101,13 @@ export default class NavBar extends React.Component { {this.state.showLogin ? : null} + {this.state.showFilter ? + + + + + + : null}
) } @@ -176,6 +198,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 +207,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 +225,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..4ecea3e --- /dev/null +++ b/client/components/googleMapTrial.js @@ -0,0 +1,88 @@ +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() { + return ( + + + + + + + + + ); + } + +}; \ 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? + + {positions.map((yup,index)=>{ + return() + })} + + {this.state.selectedPlace.title ?
+

Title: {this.state.selectedPlace.title}

+
Location: {this.state.selectedPlace.name}
+
{this.state.selectedPlace.location}
+
Artist: {this.state.selectedPlace.artistName}
+
+ :

{this.state.selectedPlace.name}

} + +
+ +
+

Hello

+
+
+ + + + +
: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..d5f7653 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", 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..9ae5918 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "body-parser": "^1.15.2", "browserify-middleware": "^7.0.0", "express": "^4.13.4", + "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", @@ -34,11 +36,23 @@ "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..bd1968d 100644 --- a/server/main.js +++ b/server/main.js @@ -2,11 +2,16 @@ 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 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,21 +22,55 @@ 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(res.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) => { + console.log("USERS MAIN",user) + console.log("USERS[0]", user[0]) if(user[0]){ res.statusMessage = "Username taken." res.status(400).end(); @@ -47,15 +86,19 @@ app.post('/signUp', function(req, res) { return db.collection('sessions').insert({id: obj._id, sessionId: sessionId}); }) .then(function(obj){ - res.send(JSON.stringify(obj.sessionId)); + console.log("SIGN UP SESSION",req.sessionID) + res.send(JSON.stringify(req.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 +120,7 @@ app.post('/login', function(req, res) { } }) .then((userObj) => { + console.log("SIGN IN SESSION",userObj.sessionId) res.send(JSON.stringify(userObj.sessionId)) }) }) @@ -220,6 +264,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; diff --git a/server/passport.js b/server/passport.js new file mode 100644 index 0000000..509d356 --- /dev/null +++ b/server/passport.js @@ -0,0 +1,169 @@ +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 passport = require("passport"); +var LocalStrategy = require('passport-local').Strategy; +var FacebookStrategy = require('passport-facebook').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) + }); + + 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 + + })) +} +// // }) + +// // } +// // )) +// } + function addFacebookUser(user,token) { + console.log('USER',user, "token" ,token) + //check if user exists. Via email. If not, make new, is yes, update existing + // return db.collection('FBusers').find({facebookID: user.id}).then(function(existingUser){ + // if(existingUser.length>0){ + // return db.collection + return db.collection('FBusers').insert({ + facebookID: user.id, + facebookToken: token, + facebookPicture: user.photos[0], + facebookName: user.name + + // facebookEmail:user.emails[0].value}) + }) + } + //create new user + // }) + + // } + + var findUserByID = function(ID) { + console.log("FINDUSERID", ID) + return db.collection('FBusers').find({ + facebookID : 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. + + // })) +// }