├── .gitignore ├── README.md ├── favicon.ico ├── nodeserver ├── index.js ├── models │ └── customers.js ├── schema.sql └── server.js ├── package.json ├── public ├── assets │ ├── icons │ │ ├── couch.png │ │ ├── door.png │ │ └── house.png │ ├── images │ │ ├── airbnb.png │ │ └── down-arrow.png │ └── styles │ │ └── grid.css ├── index.html └── map-icons │ ├── 1473327302_talk_chat_message.png │ ├── css │ └── map-icons.css │ ├── fonts │ ├── map-icons.eot │ ├── map-icons.svg │ ├── map-icons.ttf │ └── map-icons.woff │ ├── js │ └── map-icons.js │ ├── less │ └── map-icons-variables.less │ ├── price-icon.png │ ├── price-icon.psd │ └── sass │ └── map-icons-variables.scss ├── src ├── App.js ├── become-a-host │ ├── BecomeAHost.js │ ├── ChequeBox.svg │ ├── ChequedBox.svg │ ├── JSmapPractice.js │ ├── JSmapPracticeTwo.js │ ├── VerticalLinear.js │ ├── becomeahost.component.scss │ └── steps │ │ ├── BathroomIncrementer.js │ │ ├── BedIncrementer.js │ │ ├── ChequeBox.js │ │ ├── ChequedBox.js │ │ ├── GuestIncrementer.js │ │ ├── stepOne │ │ ├── Amenities.js │ │ ├── Bathrooms.js │ │ ├── Bedrooms.js │ │ ├── Location.js │ │ ├── Room.js │ │ └── Spaces.js │ │ ├── stepTwo │ │ └── Highlights.js │ │ └── steps.scss ├── common.js ├── date-range-picker │ ├── DateRangePickerGmapPage.jsx │ └── SearchBar.jsx ├── footer │ ├── Footer.js │ └── footer.scss ├── home │ ├── BelongAnywhere.js │ ├── ExploreWorld.js │ ├── Header.js │ ├── Home-search-bar.js │ ├── Home.js │ ├── HostCarousel.js │ ├── JustForWknd.js │ ├── LeftNavButton.js │ ├── OurCommunity.js │ ├── RightNavButton.js │ ├── _datepicker.scss │ └── home.component.scss ├── navbar │ ├── Navbar.js │ ├── login-modal.js │ └── navbar.component.scss ├── profile │ ├── Inbox.js │ ├── Profile.js │ ├── ProfileDash.js │ ├── inbox.scss │ └── profile.component.scss ├── rooms │ ├── About.js │ ├── Header.js │ ├── Rooms.js │ ├── Summary.js │ ├── blop.json │ ├── message-modal.js │ └── rooms.component.scss ├── search-results │ ├── SearchResults.js │ ├── config.js │ ├── date-picker-results.scss │ └── searchResults.scss ├── shared.js ├── stepper │ └── Stepper.js └── user │ └── User.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | #Node modules 2 | node_modules 3 | 4 | #Config 5 | nodeserver/config.json 6 | nodeserver/AWS/config.json 7 | 8 | #Output files 9 | public/bundle 10 | 11 | misc 12 | 13 | legacy.js 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Airbnb Clone - A React project at DevMountain 2 | 3 | ## Install 4 | 5 | Run `npm i` to install all the dependencies. 6 | 7 | ## Build 8 | 9 | Run `npm run webpack` or `webpack` to build the project. The build artifacts will be stored in the `public/bundle` directory. 10 | 11 | ## Project Description 12 | 13 | This project was built by the combined effort of Suman Bhattarai, Paxton Bigler, Jesse Hancock, and Matt Tran. The purpose was to clone portions of Airbnb.com within our limited, two-week timeframe. It was our first opportunity to implement ReactJS and various other resources that were new to one or another of us. 14 | 15 | The portions cloned include: the front page; the profile page; the listing page; the search page; and the become-a-host page. We initially conceived of building a database until we happened upon the Official Unofficial Airbnb API. Our application is able to mount information from that API similar to the native Airbnb site. The profile, listing, and search pages all use this resource. The home and become-a-host pages, are hard-coded data. 16 | 17 | The application is also mobile-responsive. 18 | 19 | ## Further help 20 | 21 | Be mindful to generate your own server config. It goes in the `nodeserver` directory. 22 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/favicon.ico -------------------------------------------------------------------------------- /nodeserver/index.js: -------------------------------------------------------------------------------- 1 | require('babel-core/register'); 2 | require('./server.js'); 3 | -------------------------------------------------------------------------------- /nodeserver/models/customers.js: -------------------------------------------------------------------------------- 1 | /* jshint indent: 2 */ 2 | 3 | module.exports = function(sequelize, DataTypes) { 4 | return sequelize.define('customers', { 5 | id: { 6 | type: DataTypes.INTEGER, 7 | allowNull: false, 8 | primaryKey: true, 9 | autoIncrement: true 10 | }, 11 | auth_id: { 12 | type: DataTypes.STRING, 13 | allowNull: false 14 | }, 15 | given_name: { 16 | type: DataTypes.STRING, 17 | allowNull: true 18 | }, 19 | family_name: { 20 | type: DataTypes.STRING, 21 | allowNull: true 22 | }, 23 | full_name: { 24 | type: DataTypes.STRING, 25 | allowNull: true 26 | }, 27 | phone: { 28 | type: DataTypes.STRING, 29 | allowNull: true 30 | }, 31 | address: { 32 | type: DataTypes.STRING, 33 | allowNull: true 34 | }, 35 | city: { 36 | type: DataTypes.STRING, 37 | allowNull: true 38 | }, 39 | state: { 40 | type: DataTypes.CHAR, 41 | allowNull: true 42 | }, 43 | zip: { 44 | type: DataTypes.CHAR, 45 | allowNull: true 46 | }, 47 | gender: { 48 | type: DataTypes.CHAR, 49 | allowNull: true 50 | }, 51 | description: { 52 | type: DataTypes.TEXT, 53 | allowNull: true 54 | } 55 | }, { 56 | tableName: 'customers' 57 | }); 58 | }; 59 | -------------------------------------------------------------------------------- /nodeserver/schema.sql: -------------------------------------------------------------------------------- 1 | create table customers ( 2 | id serial not null primary key, 3 | auth_id varchar(30) not null, 4 | given_name varchar(35), 5 | family_name varchar(35), 6 | full_name varchar(70), 7 | phone varchar(20), 8 | address varchar(32), 9 | city varchar(32), 10 | state char(2), 11 | zip char(5), 12 | gender char(1), 13 | description text 14 | ); -------------------------------------------------------------------------------- /nodeserver/server.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import cors from 'cors'; 3 | import bodyParser from 'body-parser'; 4 | import session from 'express-session'; 5 | import passport from 'passport'; 6 | import massive from 'massive'; 7 | import path from 'path'; 8 | import request from 'request'; 9 | import moment from 'moment' 10 | 11 | var inspect = require('eyespect').inspector(); 12 | var airbnb = require('airapi'); 13 | 14 | // Configs 15 | import serverConfig from './config.json'; 16 | 17 | const connectionString = serverConfig.postgresPath; //database path 18 | const app = module.exports = express(); 19 | 20 | app.use(express.static(__dirname + '/../public')); 21 | 22 | app.use('/node_modules', express.static('./node_modules')); 23 | var http = require('http').Server(app); 24 | var io = require('socket.io')(http); 25 | 26 | app.use(session({ 27 | secret: serverConfig.sessionSecret, //session secret 28 | saveUninitialized: false, 29 | resave: true 30 | })); 31 | 32 | app.use(passport.initialize()); 33 | app.use(passport.session()); 34 | app.use(cors()); 35 | app.use(bodyParser.json({ 36 | limit: '50mb' 37 | })); 38 | app.use(bodyParser.urlencoded({ 39 | limit: '50mb', 40 | extended: true 41 | })); 42 | 43 | passport.serializeUser(function(user, done) { 44 | done(null, user); 45 | }); 46 | 47 | passport.deserializeUser(function(user, done) { 48 | done(null, user); 49 | }); 50 | 51 | app.post('/login', (req, response, next) => { 52 | 53 | var config = {"X-Airbnb-OAuth-Token": "446qdnlk8o0j79zjz4py8mrum"}; 54 | var data = { 55 | client_id: "d306zoyjsyarp7ifhu67rjxn52tv0t20", 56 | currency: 'USD', 57 | grant_type: 'password', 58 | locale: "en-US", 59 | username: req.body.email, 60 | password: req.body.password 61 | }; 62 | var options = { 63 | method: 'post', 64 | url: 'https://api.airbnb.com/v1/authorize', 65 | body: data, 66 | json: true, 67 | }; 68 | 69 | request(options, (err, res, body) => { 70 | if (err) inspect(err, 'error at jsoning'); 71 | req.session.token = body.access_token; 72 | var headers = res.headers 73 | var statusCode = res.statusCode 74 | inspect(headers, 'headers') 75 | inspect(statusCode, 'statusCode') 76 | inspect(body, 'body') 77 | 78 | options.method = 'get' 79 | options.url = 'https://api.airbnb.com/v1/account/active' 80 | options.headers = {"X-Airbnb-OAuth-Token": req.session.token} 81 | options.data = null 82 | 83 | request(options, (err, res, body) => { 84 | req.session.data = body 85 | return response.json("data": req.session.data); 86 | }) 87 | 88 | }) 89 | }) 90 | 91 | app.get('/dashboard', (req, res, next) => { 92 | res.json({"data": req.session.data}); 93 | }) 94 | 95 | app.get('/getMessages', (req, response, next) => { 96 | 97 | if(req.session.token === undefined){ 98 | req.session.token = '446qdnlk8o0j79zjz4py8mrum' 99 | console.log('req.session.token: ', req.session.token) 100 | } 101 | 102 | const options = { 103 | method: 'GET', 104 | url: 'https://api.airbnb.com/v1/threads?locale=en-US&client_id=3092nxybyb0otqw18e8nh5nty&offset=0&items_per_page=10¤cy=USD&role=guest', 105 | headers: {"X-Airbnb-OAuth-Token": req.session.token}, 106 | json: true, 107 | } 108 | 109 | request(options, (err, res, body) => { 110 | if(err){ console.log(err)} 111 | console.log('res.body: ', res.body) 112 | return response.json({"threads": res.body.threads}) 113 | }) 114 | }) 115 | 116 | app.get('/getData', (req, res, next) => { 117 | if (req.session.searchResults) { 118 | res.json(req.session.searchResults); 119 | } else { 120 | airbnb.search({ 121 | location: 'Manila', 122 | checkin: '10/24/2016', 123 | checkout: '10/31/2016', 124 | guests: 2, 125 | page: 2, 126 | }).then(function(searchResults) { 127 | 128 | searchResults.location = 'Manila' 129 | searchResults.startDate = '10/24/2016' 130 | searchResults.endDate = '10/31/2016' 131 | searchResults.numGuests = 1 132 | res.json(searchResults); 133 | }); 134 | } 135 | }); 136 | 137 | app.get('/viewUser/:id', (req, response, next) => { 138 | console.log('Params: ' , req.params) 139 | const options = { 140 | method: 'get', 141 | url: `https://api.airbnb.com/v2/users/${req.params.id}?client_id=3092nxybyb0otqw18e8nh5nty&_format=v1_legacy_show`, 142 | headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}, 143 | json: true 144 | } 145 | 146 | request(options, (err, res, body) => { 147 | // console.log('user res: ', res) 148 | // console.log('user body: ', body) 149 | response.json({'succces': body}) 150 | }) 151 | 152 | }) 153 | 154 | app.post('/search', (req, res, next) => { 155 | 156 | airbnb.search({ 157 | location: req.body.searchVal, 158 | checkin: req.body.startDate, 159 | checkout: req.body.endDate, 160 | guests: req.body.numGuests, 161 | page: Math.round(Math.random()*10), 162 | room_types: req.body.room_types, 163 | price_min: req.body.price_min, 164 | price_max: req.body.price_max 165 | }).then(function(searchResults) { 166 | searchResults.location = req.body.searchVal 167 | searchResults.startDate = req.body.startDate 168 | searchResults.endDate = req.body.endDate 169 | searchResults.numGuests = req.body.numGuests 170 | 171 | req.session.searchResults = searchResults; 172 | 173 | res.json(req.session.searchResults); 174 | }); 175 | }) 176 | 177 | 178 | app.post('/sendMessage', (req, res, next) => { 179 | 180 | // THIS NEEDS TO HAVE NEW DATA 181 | console.log(req.body) 182 | var config = {"X-Airbnb-OAuth-Token": "ay8njrze1oalc9wgyfp26e67j"}; 183 | 184 | var data = { 185 | listing_id: req.body.id, 186 | number_of_guests: "1", 187 | client_id: "d306zoyjsyarp7ifhu67rjxn52tv0t20", 188 | currency: 'USD', 189 | checkout_date: "2018-04-02T22:00:00.000-0700", 190 | checkin_date: "2018-04-01T00:00:00.000-0700", 191 | locale: "en-US", 192 | message: req.body.message 193 | }; 194 | 195 | var options = { 196 | method: 'post', 197 | url: 'https://api.airbnb.com/v1/threads/create', 198 | headers: { 199 | 'X-Airbnb-OAuth-Token': 'ay8njrze1oalc9wgyfp26e67j' 200 | }, 201 | body: data, 202 | json: true 203 | }; 204 | console.log('data to be sent:', data) 205 | request(options, function(err, res, body) { 206 | console.log('body: ',body) 207 | if (err) {inspect(err, 'error at jsoning') 208 | console.log(err) 209 | }; 210 | var headers = res.headers 211 | var statusCode = res.statusCode 212 | }) 213 | }) 214 | 215 | 216 | app.get('/listingInfo/:rid', (req,res,next) => { 217 | console.log(req.params) 218 | airbnb.getInfo(req.params.rid).then(function(info) { 219 | console.log("info: ", info); 220 | res.json(info); 221 | }); 222 | }) 223 | 224 | 225 | app.get('*', function(request, response) { 226 | response.sendFile(path.resolve(__dirname, '../public', 'index.html')) 227 | }); 228 | 229 | http.listen(3000, function() { 230 | console.log('Hosting port: ', 3000); 231 | }); 232 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-strangebnb", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "nodeserver/index.js", 6 | "dependencies": { 7 | "airapi": "^0.1.0", 8 | "axios": "^0.14.0", 9 | "babel-core": "^6.14.0", 10 | "babel-loader": "^6.2.5", 11 | "babel-polyfill": "^6.13.0", 12 | "babel-runtime": "^6.11.6", 13 | "body-parser": "^1.15.2", 14 | "cors": "^2.8.0", 15 | "express": "^4.14.0", 16 | "express-session": "^1.14.1", 17 | "eyespect": "^0.1.10", 18 | "google-map-react": "^0.19.0", 19 | "jquery": "^3.1.0", 20 | "jwt-decode": "^2.1.0", 21 | "lodash": "^4.17.4", 22 | "massive": "^2.5.0", 23 | "material-ui": "^0.16.4", 24 | "moment": "^2.14.1", 25 | "node-sass": "^3.8.0", 26 | "normalize.css": "^4.2.0", 27 | "npm": "^3.10.6", 28 | "passport": "^0.3.2", 29 | "path": "^0.12.7", 30 | "radium": "^0.18.1", 31 | "react": "^15.4.2", 32 | "react-addons-shallow-compare": "^15.3.1", 33 | "react-burger-menu": "^1.10.4", 34 | "react-dates": "^2.1.1", 35 | "react-dom": "^15.4.2", 36 | "react-gmaps": "^1.5.0", 37 | "react-router": "^2.7.0", 38 | "react-slick": "^0.13.6", 39 | "react-tap-event-plugin": "^2.0.1", 40 | "request": "^2.74.0", 41 | "rheostat": "^2.0.0", 42 | "slick-carousel": "^1.6.0", 43 | "socket.io": "^1.4.8" 44 | }, 45 | "devDependencies": { 46 | "@kadira/storybook": "^2.11.0", 47 | "babel-core": "^6.14.0", 48 | "babel-loader": "^6.2.5", 49 | "babel-plugin-syntax-class-properties": "^6.13.0", 50 | "babel-plugin-transform-class-properties": "^6.11.5", 51 | "babel-plugin-transform-runtime": "^6.15.0", 52 | "babel-preset-es2015": "^6.14.0", 53 | "babel-preset-react": "^6.11.1", 54 | "babel-preset-stage-0": "^6.5.0", 55 | "css-loader": "^0.24.0", 56 | "markerwithlabel": "^2.0.0", 57 | "moment": "^2.14.1", 58 | "react": "^15.3.1", 59 | "react-addons-shallow-compare": "^15.3.1", 60 | "react-dates": "^2.1.1", 61 | "react-dom": "^15.3.1", 62 | "react-hot-loader": "^3.0.0-beta.3", 63 | "react-pure-render": "^1.0.2", 64 | "react-svg": "^1.1.2", 65 | "sass-loader": "^4.0.1", 66 | "style-loader": "^0.13.1", 67 | "webpack": "^1.13.2", 68 | "webpack-dev-server": "^1.15.1", 69 | "webpack-error-notification": "^0.1.6" 70 | }, 71 | "scripts": { 72 | "test": "echo \"Error: no test specified\" && exit 1", 73 | "dev": "webpack-dev-server --content-base public --inline --hot", 74 | "webpack": "webpack --config=webpack.config.js --display-error-details" 75 | }, 76 | "author": "", 77 | "license": "ISC", 78 | "babel": { 79 | "presets": [ 80 | "react", 81 | "es2015", 82 | "stage-0" 83 | ] 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /public/assets/icons/couch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/assets/icons/couch.png -------------------------------------------------------------------------------- /public/assets/icons/door.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/assets/icons/door.png -------------------------------------------------------------------------------- /public/assets/icons/house.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/assets/icons/house.png -------------------------------------------------------------------------------- /public/assets/images/airbnb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/assets/images/airbnb.png -------------------------------------------------------------------------------- /public/assets/images/down-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/assets/images/down-arrow.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Strangebnb 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
Loading...
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /public/map-icons/1473327302_talk_chat_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/map-icons/1473327302_talk_chat_message.png -------------------------------------------------------------------------------- /public/map-icons/fonts/map-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/map-icons/fonts/map-icons.eot -------------------------------------------------------------------------------- /public/map-icons/fonts/map-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/map-icons/fonts/map-icons.ttf -------------------------------------------------------------------------------- /public/map-icons/fonts/map-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/map-icons/fonts/map-icons.woff -------------------------------------------------------------------------------- /public/map-icons/js/map-icons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Map Icons created by Scott de Jonge 3 | * 4 | * @version 3.0.0 5 | * @url http://map-icons.com 6 | * 7 | */ 8 | 9 | // Define Marker Shapes 10 | var MAP_PIN = 'M0-48c-9.8 0-17.7 7.8-17.7 17.4 0 15.5 17.7 30.6 17.7 30.6s17.7-15.4 17.7-30.6c0-9.6-7.9-17.4-17.7-17.4z'; 11 | var SQUARE_PIN = 'M22-48h-44v43h16l6 5 6-5h16z'; 12 | var SHIELD = 'M18.8-31.8c.3-3.4 1.3-6.6 3.2-9.5l-7-6.7c-2.2 1.8-4.8 2.8-7.6 3-2.6.2-5.1-.2-7.5-1.4-2.4 1.1-4.9 1.6-7.5 1.4-2.7-.2-5.1-1.1-7.3-2.7l-7.1 6.7c1.7 2.9 2.7 6 2.9 9.2.1 1.5-.3 3.5-1.3 6.1-.5 1.5-.9 2.7-1.2 3.8-.2 1-.4 1.9-.5 2.5 0 2.8.8 5.3 2.5 7.5 1.3 1.6 3.5 3.4 6.5 5.4 3.3 1.6 5.8 2.6 7.6 3.1.5.2 1 .4 1.5.7l1.5.6c1.2.7 2 1.4 2.4 2.1.5-.8 1.3-1.5 2.4-2.1.7-.3 1.3-.5 1.9-.8.5-.2.9-.4 1.1-.5.4-.1.9-.3 1.5-.6.6-.2 1.3-.5 2.2-.8 1.7-.6 3-1.1 3.8-1.6 2.9-2 5.1-3.8 6.4-5.3 1.7-2.2 2.6-4.8 2.5-7.6-.1-1.3-.7-3.3-1.7-6.1-.9-2.8-1.3-4.9-1.2-6.4z'; 13 | var ROUTE = 'M24-28.3c-.2-13.3-7.9-18.5-8.3-18.7l-1.2-.8-1.2.8c-2 1.4-4.1 2-6.1 2-3.4 0-5.8-1.9-5.9-1.9l-1.3-1.1-1.3 1.1c-.1.1-2.5 1.9-5.9 1.9-2.1 0-4.1-.7-6.1-2l-1.2-.8-1.2.8c-.8.6-8 5.9-8.2 18.7-.2 1.1 2.9 22.2 23.9 28.3 22.9-6.7 24.1-26.9 24-28.3z'; 14 | var SQUARE = 'M-24-48h48v48h-48z'; 15 | var SQUARE_ROUNDED = 'M24-8c0 4.4-3.6 8-8 8h-32c-4.4 0-8-3.6-8-8v-32c0-4.4 3.6-8 8-8h32c4.4 0 8 3.6 8 8v32z'; 16 | 17 | // Function to do the inheritance properly 18 | // Inspired by: http://stackoverflow.com/questions/9812783/cannot-inherit-google-maps-map-v3-in-my-custom-class-javascript 19 | var inherits = function(childCtor, parentCtor) { 20 | 21 | function tempCtor() {}; 22 | tempCtor.prototype = parentCtor.prototype; 23 | childCtor.superClass_ = parentCtor.prototype; 24 | childCtor.prototype = new tempCtor(); 25 | childCtor.prototype.constructor = childCtor; 26 | }; 27 | 28 | function Marker(options){ 29 | google.maps.Marker.apply(this, arguments); 30 | 31 | if (options.map_icon_label) { 32 | this.MarkerLabel = new MarkerLabel({ 33 | map: this.map, 34 | marker: this, 35 | text: options.map_icon_label 36 | }); 37 | this.MarkerLabel.bindTo('position', this, 'position'); 38 | } 39 | } 40 | 41 | // Apply the inheritance 42 | inherits(Marker, google.maps.Marker); 43 | 44 | // Custom Marker SetMap 45 | Marker.prototype.setMap = function() { 46 | google.maps.Marker.prototype.setMap.apply(this, arguments); 47 | (this.MarkerLabel) && this.MarkerLabel.setMap.apply(this.MarkerLabel, arguments); 48 | }; 49 | 50 | // Marker Label Overlay 51 | var MarkerLabel = function(options) { 52 | var self = this; 53 | this.setValues(options); 54 | 55 | // Create the label container 56 | this.div = document.createElement('div'); 57 | this.div.className = 'map-icon-label'; 58 | 59 | // Trigger the marker click handler if clicking on the label 60 | google.maps.event.addDomListener(this.div, 'click', function(e){ 61 | (e.stopPropagation) && e.stopPropagation(); 62 | google.maps.event.trigger(self.marker, 'click'); 63 | }); 64 | //what to listen to, event, and what to do on the event. 65 | }; 66 | 67 | // Create MarkerLabel Object 68 | MarkerLabel.prototype = new google.maps.OverlayView; 69 | 70 | // Marker Label onAdd 71 | MarkerLabel.prototype.onAdd = function() { 72 | var pane = this.getPanes().overlayImage.appendChild(this.div); 73 | var self = this; 74 | 75 | this.listeners = [ 76 | google.maps.event.addListener(this, 'position_changed', function() { self.draw(); }), 77 | google.maps.event.addListener(this, 'text_changed', function() { self.draw(); }), 78 | google.maps.event.addListener(this, 'zindex_changed', function() { self.draw(); }) 79 | ]; 80 | }; 81 | 82 | // Marker Label onRemove 83 | MarkerLabel.prototype.onRemove = function() { 84 | 85 | this.div.parentNode.removeChild(this.div); 86 | 87 | for (var i = 0, I = this.listeners.length; i < I; ++i) { 88 | google.maps.event.removeListener(this.listeners[i]); 89 | } 90 | }; 91 | 92 | // Implement draw 93 | MarkerLabel.prototype.draw = function() { 94 | // console.log('MARKER LABEL THIS: ' , this.text); 95 | var projection = this.getProjection(); 96 | var position = projection.fromLatLngToDivPixel(this.get('position')); 97 | var div = this.div; 98 | 99 | this.div.innerHTML = this.get('text').toString(); 100 | 101 | div.style.zIndex = this.get('zIndex'); // Allow label to overlay marker 102 | div.style.position = 'absolute'; 103 | div.style.display = 'block'; 104 | div.style.left = (position.x - (div.offsetWidth / 2)) + 'px'; 105 | div.style.top = (position.y - div.offsetHeight-14) + 'px'; 106 | div.style.padding = '5px'; 107 | div.style.textAlign = 'center'; 108 | 109 | var img = document.createElement('img'); 110 | 111 | img.src = this.image_; 112 | img.style.zIndex = '0'; 113 | img.style.width = '60px'; 114 | img.style.position = 'absolute'; 115 | // img.style.height = '100%'; 116 | img.style.top = '-6px' 117 | img.style.left = '-19px'; 118 | img.src = "map-icons/price-icon.png"; 119 | div.appendChild(img) 120 | 121 | var p = document.createElement('p'); 122 | 123 | p.innerHTML = this.text 124 | p.style.zIndex = '0'; 125 | p.style.width = '100%'; 126 | p.style.position = 'absolute'; 127 | // img.style.height = '100%'; 128 | p.style.top = '11.5px' 129 | p.style.left = '-5px'; 130 | p.style.padding = 0; 131 | p.style.margin = 0; 132 | div.appendChild(p); 133 | 134 | }; 135 | -------------------------------------------------------------------------------- /public/map-icons/less/map-icons-variables.less: -------------------------------------------------------------------------------- 1 | @map-icon-abseiling: "\e800"; 2 | @map-icon-accounting: "\e801"; 3 | @map-icon-airport: "\e802"; 4 | @map-icon-amusement-park: "\e803"; 5 | @map-icon-aquarium: "\e804"; 6 | @map-icon-archery: "\e805"; 7 | @map-icon-art-gallery: "\e806"; 8 | @map-icon-assistive-listening-system: "\e807"; 9 | @map-icon-atm: "\e808"; 10 | @map-icon-audio-description: "\e809"; 11 | @map-icon-bakery: "\e80a"; 12 | @map-icon-bank: "\e80b"; 13 | @map-icon-bar: "\e80c"; 14 | @map-icon-baseball: "\e80d"; 15 | @map-icon-beauty-salon: "\e80e"; 16 | @map-icon-bicycle-store: "\e80f"; 17 | @map-icon-bicycling: "\e810"; 18 | @map-icon-boat-ramp: "\e811"; 19 | @map-icon-boat-tour: "\e812"; 20 | @map-icon-boating: "\e813"; 21 | @map-icon-book-store: "\e814"; 22 | @map-icon-bowling-alley: "\e815"; 23 | @map-icon-braille: "\e816"; 24 | @map-icon-bus-station: "\e817"; 25 | @map-icon-cafe: "\e818"; 26 | @map-icon-campground: "\e819"; 27 | @map-icon-canoe: "\e81a"; 28 | @map-icon-car-dealer: "\e81b"; 29 | @map-icon-car-rental: "\e81c"; 30 | @map-icon-car-repair: "\e81d"; 31 | @map-icon-car-wash: "\e81e"; 32 | @map-icon-casino: "\e81f"; 33 | @map-icon-cemetery: "\e820"; 34 | @map-icon-chairlift: "\e821"; 35 | @map-icon-church: "\e822"; 36 | @map-icon-circle: "\e823"; 37 | @map-icon-city-hall: "\e824"; 38 | @map-icon-climbing: "\e825"; 39 | @map-icon-closed-captioning: "\e826"; 40 | @map-icon-clothing-store: "\e827"; 41 | @map-icon-compass: "\e828"; 42 | @map-icon-convenience-store: "\e829"; 43 | @map-icon-courthouse: "\e82a"; 44 | @map-icon-cross-country-skiing: "\e82b"; 45 | @map-icon-crosshairs: "\e82c"; 46 | @map-icon-dentist: "\e82d"; 47 | @map-icon-department-store: "\e82e"; 48 | @map-icon-diving: "\e82f"; 49 | @map-icon-doctor: "\e830"; 50 | @map-icon-electrician: "\e831"; 51 | @map-icon-electronics-store: "\e832"; 52 | @map-icon-embassy: "\e833"; 53 | @map-icon-expand: "\e834"; 54 | @map-icon-female: "\e835"; 55 | @map-icon-finance: "\e836"; 56 | @map-icon-fire-station: "\e837"; 57 | @map-icon-fish-cleaning: "\e838"; 58 | @map-icon-fishing-pier: "\e839"; 59 | @map-icon-fishing: "\e83a"; 60 | @map-icon-florist: "\e83b"; 61 | @map-icon-food: "\e83c"; 62 | @map-icon-fullscreen: "\e83d"; 63 | @map-icon-funeral-home: "\e83e"; 64 | @map-icon-furniture-store: "\e83f"; 65 | @map-icon-gas-station: "\e840"; 66 | @map-icon-general-contractor: "\e841"; 67 | @map-icon-golf: "\e842"; 68 | @map-icon-grocery-or-supermarket: "\e843"; 69 | @map-icon-gym: "\e844"; 70 | @map-icon-hair-care: "\e845"; 71 | @map-icon-hang-gliding: "\e846"; 72 | @map-icon-hardware-store: "\e847"; 73 | @map-icon-health: "\e848"; 74 | @map-icon-hindu-temple: "\e849"; 75 | @map-icon-horse-riding: "\e84a"; 76 | @map-icon-hospital: "\e84b"; 77 | @map-icon-ice-fishing: "\e84c"; 78 | @map-icon-ice-skating: "\e84d"; 79 | @map-icon-inline-skating: "\e84e"; 80 | @map-icon-insurance-agency: "\e84f"; 81 | @map-icon-jet-skiing: "\e850"; 82 | @map-icon-jewelry-store: "\e851"; 83 | @map-icon-kayaking: "\e852"; 84 | @map-icon-laundry: "\e853"; 85 | @map-icon-lawyer: "\e854"; 86 | @map-icon-library: "\e855"; 87 | @map-icon-liquor-store: "\e856"; 88 | @map-icon-local-government: "\e857"; 89 | @map-icon-location-arrow: "\e858"; 90 | @map-icon-locksmith: "\e859"; 91 | @map-icon-lodging: "\e85a"; 92 | @map-icon-low-vision-access: "\e85b"; 93 | @map-icon-male: "\e85c"; 94 | @map-icon-map-pin: "\e85d"; 95 | @map-icon-marina: "\e85e"; 96 | @map-icon-mosque: "\e85f"; 97 | @map-icon-motobike-trail: "\e860"; 98 | @map-icon-movie-rental: "\e861"; 99 | @map-icon-movie-theater: "\e862"; 100 | @map-icon-moving-company: "\e863"; 101 | @map-icon-museum: "\e864"; 102 | @map-icon-natural-feature: "\e865"; 103 | @map-icon-night-club: "\e866"; 104 | @map-icon-open-captioning: "\e867"; 105 | @map-icon-painter: "\e868"; 106 | @map-icon-park: "\e869"; 107 | @map-icon-parking: "\e86a"; 108 | @map-icon-pet-store: "\e86b"; 109 | @map-icon-pharmacy: "\e86c"; 110 | @map-icon-physiotherapist: "\e86d"; 111 | @map-icon-place-of-worship: "\e86e"; 112 | @map-icon-playground: "\e86f"; 113 | @map-icon-plumber: "\e870"; 114 | @map-icon-point-of-interest: "\e871"; 115 | @map-icon-police: "\e872"; 116 | @map-icon-political: "\e873"; 117 | @map-icon-post-box: "\e874"; 118 | @map-icon-post-office: "\e875"; 119 | @map-icon-postal-code-prefix: "\e876"; 120 | @map-icon-postal-code: "\e877"; 121 | @map-icon-rafting: "\e878"; 122 | @map-icon-real-estate-agency: "\e879"; 123 | @map-icon-restaurant: "\e87a"; 124 | @map-icon-roofing-contractor: "\e87b"; 125 | @map-icon-route-pin: "\e87c"; 126 | @map-icon-route: "\e87d"; 127 | @map-icon-rv-park: "\e87e"; 128 | @map-icon-sailing: "\e87f"; 129 | @map-icon-school: "\e880"; 130 | @map-icon-scuba-diving: "\e881"; 131 | @map-icon-search: "\e882"; 132 | @map-icon-shield: "\e883"; 133 | @map-icon-shopping-mall: "\e884"; 134 | @map-icon-sign-language: "\e885"; 135 | @map-icon-skateboarding: "\e886"; 136 | @map-icon-ski-jumping: "\e887"; 137 | @map-icon-skiing: "\e888"; 138 | @map-icon-sledding: "\e889"; 139 | @map-icon-snow-shoeing: "\e88a"; 140 | @map-icon-snow: "\e88b"; 141 | @map-icon-snowboarding: "\e88c"; 142 | @map-icon-snowmobile: "\e88d"; 143 | @map-icon-spa: "\e88e"; 144 | @map-icon-square-pin: "\e88f"; 145 | @map-icon-square-rounded: "\e890"; 146 | @map-icon-square: "\e891"; 147 | @map-icon-stadium: "\e892"; 148 | @map-icon-storage: "\e893"; 149 | @map-icon-store: "\e894"; 150 | @map-icon-subway-station: "\e895"; 151 | @map-icon-surfing: "\e896"; 152 | @map-icon-swimming: "\e897"; 153 | @map-icon-synagogue: "\e898"; 154 | @map-icon-taxi-stand: "\e899"; 155 | @map-icon-tennis: "\e89a"; 156 | @map-icon-toilet: "\e89b"; 157 | @map-icon-trail-walking: "\e89c"; 158 | @map-icon-train-station: "\e89d"; 159 | @map-icon-transit-station: "\e89e"; 160 | @map-icon-travel-agency: "\e89f"; 161 | @map-icon-unisex: "\e8a0"; 162 | @map-icon-university: "\e8a1"; 163 | @map-icon-veterinary-care: "\e8a2"; 164 | @map-icon-viewing: "\e8a3"; 165 | @map-icon-volume-control-telephone: "\e8a4"; 166 | @map-icon-walking: "\e8a5"; 167 | @map-icon-waterskiing: "\e8a6"; 168 | @map-icon-whale-watching: "\e8a7"; 169 | @map-icon-wheelchair: "\e8a8"; 170 | @map-icon-wind-surfing: "\e8a9"; 171 | @map-icon-zoo: "\e8aa"; 172 | @map-icon-zoom-in-alt: "\e8ab"; 173 | @map-icon-zoom-in: "\e8ac"; 174 | @map-icon-zoom-out-alt: "\e8ad"; 175 | @map-icon-zoom-out: "\e8ae"; 176 | -------------------------------------------------------------------------------- /public/map-icons/price-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/map-icons/price-icon.png -------------------------------------------------------------------------------- /public/map-icons/price-icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangebnb/react-airbnb/949c53b9afeff6844a971215fab0a6c20970db40/public/map-icons/price-icon.psd -------------------------------------------------------------------------------- /public/map-icons/sass/map-icons-variables.scss: -------------------------------------------------------------------------------- 1 | $map-icon-abseiling: "\e800"; 2 | $map-icon-accounting: "\e801"; 3 | $map-icon-airport: "\e802"; 4 | $map-icon-amusement-park: "\e803"; 5 | $map-icon-aquarium: "\e804"; 6 | $map-icon-archery: "\e805"; 7 | $map-icon-art-gallery: "\e806"; 8 | $map-icon-assistive-listening-system: "\e807"; 9 | $map-icon-atm: "\e808"; 10 | $map-icon-audio-description: "\e809"; 11 | $map-icon-bakery: "\e80a"; 12 | $map-icon-bank: "\e80b"; 13 | $map-icon-bar: "\e80c"; 14 | $map-icon-baseball: "\e80d"; 15 | $map-icon-beauty-salon: "\e80e"; 16 | $map-icon-bicycle-store: "\e80f"; 17 | $map-icon-bicycling: "\e810"; 18 | $map-icon-boat-ramp: "\e811"; 19 | $map-icon-boat-tour: "\e812"; 20 | $map-icon-boating: "\e813"; 21 | $map-icon-book-store: "\e814"; 22 | $map-icon-bowling-alley: "\e815"; 23 | $map-icon-braille: "\e816"; 24 | $map-icon-bus-station: "\e817"; 25 | $map-icon-cafe: "\e818"; 26 | $map-icon-campground: "\e819"; 27 | $map-icon-canoe: "\e81a"; 28 | $map-icon-car-dealer: "\e81b"; 29 | $map-icon-car-rental: "\e81c"; 30 | $map-icon-car-repair: "\e81d"; 31 | $map-icon-car-wash: "\e81e"; 32 | $map-icon-casino: "\e81f"; 33 | $map-icon-cemetery: "\e820"; 34 | $map-icon-chairlift: "\e821"; 35 | $map-icon-church: "\e822"; 36 | $map-icon-circle: "\e823"; 37 | $map-icon-city-hall: "\e824"; 38 | $map-icon-climbing: "\e825"; 39 | $map-icon-closed-captioning: "\e826"; 40 | $map-icon-clothing-store: "\e827"; 41 | $map-icon-compass: "\e828"; 42 | $map-icon-convenience-store: "\e829"; 43 | $map-icon-courthouse: "\e82a"; 44 | $map-icon-cross-country-skiing: "\e82b"; 45 | $map-icon-crosshairs: "\e82c"; 46 | $map-icon-dentist: "\e82d"; 47 | $map-icon-department-store: "\e82e"; 48 | $map-icon-diving: "\e82f"; 49 | $map-icon-doctor: "\e830"; 50 | $map-icon-electrician: "\e831"; 51 | $map-icon-electronics-store: "\e832"; 52 | $map-icon-embassy: "\e833"; 53 | $map-icon-expand: "\e834"; 54 | $map-icon-female: "\e835"; 55 | $map-icon-finance: "\e836"; 56 | $map-icon-fire-station: "\e837"; 57 | $map-icon-fish-cleaning: "\e838"; 58 | $map-icon-fishing-pier: "\e839"; 59 | $map-icon-fishing: "\e83a"; 60 | $map-icon-florist: "\e83b"; 61 | $map-icon-food: "\e83c"; 62 | $map-icon-fullscreen: "\e83d"; 63 | $map-icon-funeral-home: "\e83e"; 64 | $map-icon-furniture-store: "\e83f"; 65 | $map-icon-gas-station: "\e840"; 66 | $map-icon-general-contractor: "\e841"; 67 | $map-icon-golf: "\e842"; 68 | $map-icon-grocery-or-supermarket: "\e843"; 69 | $map-icon-gym: "\e844"; 70 | $map-icon-hair-care: "\e845"; 71 | $map-icon-hang-gliding: "\e846"; 72 | $map-icon-hardware-store: "\e847"; 73 | $map-icon-health: "\e848"; 74 | $map-icon-hindu-temple: "\e849"; 75 | $map-icon-horse-riding: "\e84a"; 76 | $map-icon-hospital: "\e84b"; 77 | $map-icon-ice-fishing: "\e84c"; 78 | $map-icon-ice-skating: "\e84d"; 79 | $map-icon-inline-skating: "\e84e"; 80 | $map-icon-insurance-agency: "\e84f"; 81 | $map-icon-jet-skiing: "\e850"; 82 | $map-icon-jewelry-store: "\e851"; 83 | $map-icon-kayaking: "\e852"; 84 | $map-icon-laundry: "\e853"; 85 | $map-icon-lawyer: "\e854"; 86 | $map-icon-library: "\e855"; 87 | $map-icon-liquor-store: "\e856"; 88 | $map-icon-local-government: "\e857"; 89 | $map-icon-location-arrow: "\e858"; 90 | $map-icon-locksmith: "\e859"; 91 | $map-icon-lodging: "\e85a"; 92 | $map-icon-low-vision-access: "\e85b"; 93 | $map-icon-male: "\e85c"; 94 | $map-icon-map-pin: "\e85d"; 95 | $map-icon-marina: "\e85e"; 96 | $map-icon-mosque: "\e85f"; 97 | $map-icon-motobike-trail: "\e860"; 98 | $map-icon-movie-rental: "\e861"; 99 | $map-icon-movie-theater: "\e862"; 100 | $map-icon-moving-company: "\e863"; 101 | $map-icon-museum: "\e864"; 102 | $map-icon-natural-feature: "\e865"; 103 | $map-icon-night-club: "\e866"; 104 | $map-icon-open-captioning: "\e867"; 105 | $map-icon-painter: "\e868"; 106 | $map-icon-park: "\e869"; 107 | $map-icon-parking: "\e86a"; 108 | $map-icon-pet-store: "\e86b"; 109 | $map-icon-pharmacy: "\e86c"; 110 | $map-icon-physiotherapist: "\e86d"; 111 | $map-icon-place-of-worship: "\e86e"; 112 | $map-icon-playground: "\e86f"; 113 | $map-icon-plumber: "\e870"; 114 | $map-icon-point-of-interest: "\e871"; 115 | $map-icon-police: "\e872"; 116 | $map-icon-political: "\e873"; 117 | $map-icon-post-box: "\e874"; 118 | $map-icon-post-office: "\e875"; 119 | $map-icon-postal-code-prefix: "\e876"; 120 | $map-icon-postal-code: "\e877"; 121 | $map-icon-rafting: "\e878"; 122 | $map-icon-real-estate-agency: "\e879"; 123 | $map-icon-restaurant: "\e87a"; 124 | $map-icon-roofing-contractor: "\e87b"; 125 | $map-icon-route-pin: "\e87c"; 126 | $map-icon-route: "\e87d"; 127 | $map-icon-rv-park: "\e87e"; 128 | $map-icon-sailing: "\e87f"; 129 | $map-icon-school: "\e880"; 130 | $map-icon-scuba-diving: "\e881"; 131 | $map-icon-search: "\e882"; 132 | $map-icon-shield: "\e883"; 133 | $map-icon-shopping-mall: "\e884"; 134 | $map-icon-sign-language: "\e885"; 135 | $map-icon-skateboarding: "\e886"; 136 | $map-icon-ski-jumping: "\e887"; 137 | $map-icon-skiing: "\e888"; 138 | $map-icon-sledding: "\e889"; 139 | $map-icon-snow-shoeing: "\e88a"; 140 | $map-icon-snow: "\e88b"; 141 | $map-icon-snowboarding: "\e88c"; 142 | $map-icon-snowmobile: "\e88d"; 143 | $map-icon-spa: "\e88e"; 144 | $map-icon-square-pin: "\e88f"; 145 | $map-icon-square-rounded: "\e890"; 146 | $map-icon-square: "\e891"; 147 | $map-icon-stadium: "\e892"; 148 | $map-icon-storage: "\e893"; 149 | $map-icon-store: "\e894"; 150 | $map-icon-subway-station: "\e895"; 151 | $map-icon-surfing: "\e896"; 152 | $map-icon-swimming: "\e897"; 153 | $map-icon-synagogue: "\e898"; 154 | $map-icon-taxi-stand: "\e899"; 155 | $map-icon-tennis: "\e89a"; 156 | $map-icon-toilet: "\e89b"; 157 | $map-icon-trail-walking: "\e89c"; 158 | $map-icon-train-station: "\e89d"; 159 | $map-icon-transit-station: "\e89e"; 160 | $map-icon-travel-agency: "\e89f"; 161 | $map-icon-unisex: "\e8a0"; 162 | $map-icon-university: "\e8a1"; 163 | $map-icon-veterinary-care: "\e8a2"; 164 | $map-icon-viewing: "\e8a3"; 165 | $map-icon-volume-control-telephone: "\e8a4"; 166 | $map-icon-walking: "\e8a5"; 167 | $map-icon-waterskiing: "\e8a6"; 168 | $map-icon-whale-watching: "\e8a7"; 169 | $map-icon-wheelchair: "\e8a8"; 170 | $map-icon-wind-surfing: "\e8a9"; 171 | $map-icon-zoo: "\e8aa"; 172 | $map-icon-zoom-in-alt: "\e8ab"; 173 | $map-icon-zoom-in: "\e8ac"; 174 | $map-icon-zoom-out-alt: "\e8ad"; 175 | $map-icon-zoom-out: "\e8ae"; 176 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Router, Route, IndexRoute} from 'react-router' 4 | import injectTapEventPlugin from 'react-tap-event-plugin'; 5 | import { browserHistory } from 'react-router' 6 | 7 | import Navbar from './navbar/Navbar'; 8 | import Home from './home/Home'; 9 | import Footer from './footer/Footer'; 10 | 11 | import Profile from './profile/Profile'; 12 | import BecomeAHost from './become-a-host/BecomeAHost'; 13 | import Room from './become-a-host/steps/stepOne/Room'; 14 | import Bedrooms from './become-a-host/steps/stepOne/Bedrooms'; 15 | import Bathrooms from './become-a-host/steps/stepOne/Bathrooms'; 16 | import Location from './become-a-host/steps/stepOne/Location'; 17 | import Amenities from './become-a-host/steps/stepOne/Amenities'; 18 | import Spaces from './become-a-host/steps/stepOne/Spaces'; 19 | import Highlights from './become-a-host/steps/stepTwo/Highlights' 20 | import SearchResults from './search-results/SearchResults'; 21 | import LoginModal from './navbar/login-modal' 22 | import Rooms from './rooms/Rooms'; 23 | import Inbox from './profile/Inbox.js'; 24 | import User from './user/User.js'; 25 | 26 | 27 | injectTapEventPlugin(); 28 | 29 | //Routing for Navbar 30 | const App = React.createClass({ 31 | render(){ 32 | return ( 33 |
34 | 35 | {this.props.children} 36 |
37 | ) 38 | } 39 | }) 40 | 41 | ReactDOM.render(( 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | ), document.getElementById('root')); 63 | -------------------------------------------------------------------------------- /src/become-a-host/BecomeAHost.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import {Component} from 'react'; 4 | import VerticalLinearStepper from './VerticalLinear'; 5 | import Footer from '../footer/Footer'; 6 | 7 | require('./becomeahost.component.scss'); 8 | 9 | const styles ={ 10 | paddingTop: "70px", 11 | height: "100vh", 12 | width: "100vw", 13 | backgroundColor: "white", 14 | leftSide: { 15 | }, 16 | rightSide: { 17 | 18 | }, 19 | } 20 | 21 | const BecomeAHost = React.createClass ({ 22 | render() { 23 | return( 24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 |
34 |
35 |
36 |
37 |
39 | ) 40 | } 41 | }) 42 | 43 | export default BecomeAHost; 44 | -------------------------------------------------------------------------------- /src/become-a-host/ChequeBox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/become-a-host/ChequedBox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/become-a-host/JSmapPractice.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Slider from 'react-slick'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | 5 | const results = [ 6 | { listing: 7 | {name: "Renan", 8 | price: 40, 9 | pictures: [ 10 | , 11 | , 12 | , 13 | 14 | ] 15 | } 16 | } 17 | ]; 18 | 19 | export default React.createClass({ 20 | getInitialState: function() { 21 | return { results } 22 | }, 23 | render(){ 24 | var settings = { 25 | dots: true, 26 | infinite: true, 27 | speed: 600, 28 | slidesToShow: 1, 29 | slidesToScroll: 1, 30 | }; 31 | const listItems = this.state.results.map(function(result) { 32 | return ( 33 |
34 | {results} 35 |
36 | ); 37 | }); 38 | 39 | return ( 40 |
41 | 42 | {listItems} 43 | 44 |
45 | ); 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /src/become-a-host/JSmapPracticeTwo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Slider from 'react-slick'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | 5 | var items = [ 6 | { pic: }, 7 | { pic: }, 8 | { pic: }, 9 | { pic: } 10 | ]; 11 | 12 | export default React.createClass({ 13 | getInitialState: function() { 14 | return { items } 15 | }, 16 | render(){ 17 | var settings = { 18 | dots: true, 19 | infinite: true, 20 | speed: 600, 21 | slidesToShow: 1, 22 | slidesToScroll: 1, 23 | }; 24 | var listItems = this.state.items.map(function(item) { 25 | return ( 26 |
27 | {item.pic} 28 |
29 | ); 30 | }); 31 | 32 | 33 | 34 | return ( 35 |
36 | 37 | {listItems} 38 | 39 |
40 | ); 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /src/become-a-host/VerticalLinear.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Step, 4 | Stepper, 5 | StepLabel, 6 | StepContent, 7 | } from 'material-ui/Stepper'; 8 | import RaisedButton from 'material-ui/RaisedButton'; 9 | import FlatButton from 'material-ui/FlatButton'; 10 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 11 | import {Link} from 'react-router'; 12 | 13 | const styles = { 14 | stepLabel: { 15 | display: 'flex', 16 | flexDirection: 'column', 17 | }, 18 | stepNumber: { 19 | fontSize: 14, 20 | fontFamily: "Roboto", 21 | color: "#BBBBBB", 22 | alignSelf: 'flex-start', 23 | }, 24 | stepTitle: { 25 | fontSize: 24, 26 | fontFamily: "Roboto", 27 | color: "#4B4B4B", 28 | alignSelf: 'flex-start', 29 | }, 30 | stepSubtitle: { 31 | fontSize: 16, 32 | fontFamily: "Roboto", 33 | color: "#909090", 34 | alignSelf: 'flex-start', 35 | }, 36 | buttonContainer: { 37 | marginTop: 25, 38 | marginLeft: 13, 39 | paddingBottom: 20, 40 | marginBottom: 20, 41 | borderBottom: "1px solid rgba(187, 187, 187, 0.27)", 42 | }, 43 | stepTitleDisabled: { 44 | fontSize: 24, 45 | fontFamily: "Roboto", 46 | color: "#909090", 47 | alignSelf: 'flex-start', 48 | }, 49 | stepSubtitleDisabled: { 50 | fontSize: 16, 51 | fontFamily: "Roboto", 52 | color: "#BBBBBB", 53 | alignSelf: 'flex-start', 54 | }, 55 | 56 | } 57 | 58 | 59 | class VerticalLinearStepper extends React.Component { 60 | 61 | state = { 62 | finished: false, 63 | stepIndex: 0, 64 | }; 65 | 66 | handleNext = () => { 67 | const {stepIndex} = this.state; 68 | this.setState({ 69 | stepIndex: stepIndex + 1, 70 | finished: stepIndex >= 2, 71 | }); 72 | }; 73 | 74 | handlePrev = () => { 75 | const {stepIndex} = this.state; 76 | if (stepIndex > 0) { 77 | this.setState({stepIndex: stepIndex - 1}); 78 | } 79 | }; 80 | 81 | renderStepActions(step) { 82 | const {stepIndex} = this.state; 83 | 84 | return ( 85 |
86 | 96 | {step > 0 && ( 97 | 105 | )} 106 |
107 | ); 108 | } 109 | 110 | render() { 111 | const {finished, stepIndex} = this.state; 112 | 113 | return ( 114 |
115 |
116 |
Become an Airbnb host
117 |
Start off by creating a listing page. Think of it as a profile page
for your place
118 |
119 | 120 | 121 | 122 |
}> 123 |
STEP 1
124 |
Start with the basics
125 |
Beds, bathrooms, amenities, and more
126 | 127 | 128 |
129 | {this.renderStepActions(1)} 130 |
131 | 132 | 133 | 134 | }> 135 |
STEP 2
136 |
Set the scene
137 |
Photos, short description, title
138 |
139 |
140 |
141 |
142 | 143 | }> 144 |
STEP 3
145 |
Get ready for guests
146 |
price, calendar, booking settings
147 |
148 |
149 |
150 |
151 | 152 | 153 | 154 | ); 155 | } 156 | } 157 | 158 | export default VerticalLinearStepper; 159 | -------------------------------------------------------------------------------- /src/become-a-host/becomeahost.component.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/become-a-host/steps/BathroomIncrementer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default React.createClass({ 4 | decrement: function() { 5 | this.refs.counter.decrement(); 6 | }, 7 | increment: function() { 8 | this.refs.counter.increment(); 9 | }, 10 | render: function() { 11 | return ( 12 |
13 |
14 | 15 |
bathrooms
16 |
17 | 18 | 19 |
20 | ); 21 | } 22 | }); 23 | 24 | var Logic = React.createClass({ 25 | render: function() { 26 | return ( 27 |
28 | 29 | 30 |
31 | ) 32 | } 33 | }); 34 | 35 | var Counter = React.createClass({ 36 | getInitialState: function() { 37 | return { 38 | counter: 1 39 | }; 40 | }, 41 | increment: function() { 42 | this.setState({ 43 | counter: this.state.counter + 1 44 | }); 45 | }, 46 | decrement: function() { 47 | this.setState({ 48 | counter: this.state.counter - 1 49 | }); 50 | }, 51 | render: function() { 52 | return
{this.state.counter}
; 53 | } 54 | }); 55 | -------------------------------------------------------------------------------- /src/become-a-host/steps/BedIncrementer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default React.createClass({ 4 | decrement: function() { 5 | this.refs.counter.decrement(); 6 | }, 7 | increment: function() { 8 | this.refs.counter.increment(); 9 | }, 10 | render: function() { 11 | return ( 12 |
13 |
14 | 15 |
16 | {console.log("Can I log in here")} 17 | {/* {(this.state.number === 1) 18 | ?
{this.state.listing.beds} bed
19 | :
{this.state.listing.beds} beds
20 | } */} 21 | bed 22 |
23 |
24 | 25 | 26 |
27 | ); 28 | } 29 | }); 30 | 31 | var Logic = React.createClass({ 32 | render: function() { 33 | return ( 34 |
35 | 36 | 37 |
38 | ) 39 | } 40 | }); 41 | 42 | var Counter = React.createClass({ 43 | getInitialState: function() { 44 | return { 45 | counter: 1 46 | }; 47 | }, 48 | increment: function() { 49 | this.setState({ 50 | counter: this.state.counter + 1 51 | }); 52 | }, 53 | decrement: function() { 54 | this.setState({ 55 | counter: this.state.counter - 1 56 | }); 57 | }, 58 | render: function() { 59 | return
{this.state.counter}
; 60 | } 61 | }); 62 | -------------------------------------------------------------------------------- /src/become-a-host/steps/ChequeBox.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class ChequeBox extends React.Component { 4 | render(){ 5 | return( 6 |
7 | 8 |
9 | ) 10 | } 11 | } 12 | export default ChequeBox; 13 | -------------------------------------------------------------------------------- /src/become-a-host/steps/ChequedBox.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class ChequedBox extends React.Component { 4 | render(){ 5 | return( 6 |
7 | ✓ 8 |
9 | ) 10 | } 11 | } 12 | export default ChequedBox; 13 | -------------------------------------------------------------------------------- /src/become-a-host/steps/GuestIncrementer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default React.createClass({ 4 | decrement: function() { 5 | this.refs.counter.decrement(); 6 | }, 7 | increment: function() { 8 | this.refs.counter.increment(); 9 | }, 10 | render: function() { 11 | return ( 12 |
13 |
14 | 15 |
guests
16 |
17 | 18 | 19 |
20 | ); 21 | } 22 | }); 23 | 24 | var Logic = React.createClass({ 25 | render: function() { 26 | return ( 27 |
28 | 29 | 30 |
31 | ) 32 | } 33 | }); 34 | 35 | var Counter = React.createClass({ 36 | getInitialState: function() { 37 | return { 38 | counter: 1 39 | }; 40 | }, 41 | increment: function() { 42 | this.setState({ 43 | counter: this.state.counter + 1 44 | }); 45 | }, 46 | decrement: function() { 47 | this.setState({ 48 | counter: this.state.counter - 1 49 | }); 50 | }, 51 | render: function() { 52 | return
{this.state.counter}
; 53 | } 54 | }); 55 | -------------------------------------------------------------------------------- /src/become-a-host/steps/stepOne/Amenities.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import Checkbox from 'material-ui/Checkbox'; 5 | import FlatButton from 'material-ui/FlatButton'; 6 | import RaisedButton from 'material-ui/RaisedButton'; 7 | import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton'; 8 | 9 | // import ChequeBox from '../../ChequeBox.svg'; 10 | // import ChequedBox from '../../ChequedBox.svg'; 11 | import Lightbulb from 'material-ui/svg-icons/action/lightbulb-outline'; 12 | 13 | require ("../steps.scss") 14 | 15 | 16 | 17 | 18 | const styles = { 19 | box: { 20 | width: 320, 21 | height: 70, 22 | fontSize: 18, 23 | } 24 | }; 25 | 26 | export default React.createClass({ 27 | render(){ 28 | return( 29 |
30 |
31 |
32 |
33 | 34 |
Place type
35 | 36 |
37 |
38 | 39 |
Bedrooms
40 | 41 |
42 |
43 | 44 |
Baths
45 | 46 |
47 |
48 | 49 |
Location
50 | 51 |
52 |
53 | 54 |
Amenities
55 | 56 |
57 |
58 | 59 |
Shared spaces
60 | 61 |
62 |
63 |
64 | 65 |
66 |
67 |
68 |
69 |
70 |
71 |
What amenitites do you offer?
72 | 73 |
74 | 79 | 84 | 89 | 94 | 99 | 104 | 109 | 114 | 119 | 124 | 129 | 134 | 139 |
Safety Amenities
140 | 145 | 150 | 155 | 160 | 165 | 170 |
171 |
172 |
173 | 174 |
175 |
176 | 177 |
178 |
179 | 180 | 184 | 185 |
186 |
187 | 188 | 194 | 195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 | 203 |
204 |
205 | 206 | 207 | 208 |
209 |
210 |
211 |
Providing the essentials helps guests feel at home in your place.
212 |
Some hosts provide breakfast, or just coffee and tea. 213 | None of these things are required, but sometimes they add a 214 | nice touch to help guests feel welcome. 215 |
216 |
217 |
218 |
219 | 220 |
221 |
222 |
223 |
224 | ) 225 | } 226 | 227 | 228 | }) 229 | -------------------------------------------------------------------------------- /src/become-a-host/steps/stepOne/Bathrooms.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import FlatButton from 'material-ui/FlatButton'; 5 | import RaisedButton from 'material-ui/RaisedButton'; 6 | import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton'; 7 | import BathroomIncrementer from '../BathroomIncrementer' 8 | 9 | import Lightbulb from 'material-ui/svg-icons/action/lightbulb-outline'; 10 | 11 | require ("../steps.scss") 12 | 13 | 14 | 15 | 16 | const styles = { 17 | block: { 18 | maxWidth: 250, 19 | }, 20 | checkbox: { 21 | marginBottom: 16, 22 | }, 23 | customWidth: { 24 | width: 320, 25 | marginTop: '3px', 26 | border: "none", 27 | fontSize: 18, 28 | color: '#A2A2A2', 29 | }, 30 | dropDown: { 31 | backgroundColor: "#484848", 32 | fontFamily: "Roboto", 33 | width: "100%", 34 | border: "none", 35 | marginBottom: "1vh", 36 | borderRadius: "3px", 37 | }, 38 | radio: { 39 | display: "flex", 40 | justifyContent: "space-between", 41 | width: "270px", 42 | borderBottom: "1px solid #E6E6E6", 43 | height: "65px", 44 | padding: "20px 5px", 45 | paddingRight: "15px", 46 | }, 47 | placetypeIcon: { 48 | color: "#E6E6E6", 49 | borderBottom: "1px solid #E6E6E6", 50 | height: "65px", 51 | padding: "10px ", 52 | width: '48px' 53 | } 54 | }; 55 | 56 | export default React.createClass({ 57 | getInitialState() { 58 | return { 59 | value: 1, 60 | enabler: true 61 | } 62 | }, 63 | handleChange(e){ 64 | console.log(e.target.value); 65 | this.setState({ 66 | value: e.target.value, 67 | }) 68 | }, 69 | handleClick(){ 70 | this.setState({enabler: false}) 71 | }, 72 | render(){ 73 | return( 74 |
75 |
76 |
77 |
78 | 79 |
Place type
80 | 81 |
82 |
83 | 84 |
Bedrooms
85 | 86 |
87 |
88 | 89 |
Baths
90 | 91 |
92 |
93 | 94 |
Location
95 | 96 |
97 |
98 | 99 |
Amenities
100 | 101 |
102 |
103 | 104 |
Shared spaces
105 | 106 |
107 |
108 |
109 | 110 |
111 |
112 |
113 |
114 |
115 |
116 |
How many bathrooms?
117 |
118 | 119 |
120 |
121 | 122 |
123 | 124 |
125 |
126 | 127 | 131 | 132 |
133 |
134 | 135 | 141 | 142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | 150 |
151 |
152 | 153 | 154 | 155 |
156 |
157 |
If you have a toilet seperate form the shower, count is as a 0.5 bathroom.
158 |
159 |
160 | 161 |
162 |
163 |
164 |
165 |
166 | ) 167 | } 168 | 169 | 170 | }) 171 | -------------------------------------------------------------------------------- /src/become-a-host/steps/stepOne/Bedrooms.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import Checkbox from 'material-ui/Checkbox'; 5 | import DropDownMenu from 'material-ui/DropDownMenu'; 6 | import MenuItem from 'material-ui/MenuItem'; 7 | import FlatButton from 'material-ui/FlatButton'; 8 | import RaisedButton from 'material-ui/RaisedButton'; 9 | import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton'; 10 | import BedIncrementer from '../BedIncrementer' 11 | import GuestIncrementer from '../GuestIncrementer' 12 | 13 | import Lightbulb from 'material-ui/svg-icons/action/lightbulb-outline'; 14 | import Home from 'material-ui/svg-icons/action/home'; 15 | import Seat from 'material-ui/svg-icons/action/event-seat'; 16 | import Hotel from 'material-ui/svg-icons/maps/hotel'; 17 | import OpenCircle from 'material-ui/svg-icons/image/panorama-fish-eye'; 18 | import SelectedCircle from 'material-ui/svg-icons/image/adjust'; 19 | 20 | require ("../steps.scss") 21 | 22 | 23 | 24 | 25 | const styles = { 26 | block: { 27 | maxWidth: 250, 28 | }, 29 | checkbox: { 30 | marginBottom: 16, 31 | }, 32 | customWidth: { 33 | width: 320, 34 | marginTop: '3px', 35 | border: "none", 36 | fontSize: 18, 37 | color: '#A2A2A2', 38 | }, 39 | dropDown: { 40 | backgroundColor: "#484848", 41 | fontFamily: "Roboto", 42 | width: "100%", 43 | border: "none", 44 | marginBottom: "1vh", 45 | borderRadius: "3px", 46 | }, 47 | radio: { 48 | display: "flex", 49 | justifyContent: "space-between", 50 | width: "270px", 51 | borderBottom: "1px solid #E6E6E6", 52 | height: "65px", 53 | padding: "20px 5px", 54 | paddingRight: "15px", 55 | }, 56 | placetypeIcon: { 57 | color: "#E6E6E6", 58 | borderBottom: "1px solid #E6E6E6", 59 | height: "65px", 60 | padding: "10px ", 61 | width: '48px' 62 | } 63 | }; 64 | 65 | export default React.createClass({ 66 | getInitialState() { 67 | return { 68 | value: 1, 69 | enabler: true, 70 | bed: 1 71 | } 72 | }, 73 | handleChange(event, index, value){ 74 | this.setState({value}) 75 | }, 76 | handleChangeTwo(event, index, bed){ 77 | this.setState({bed}) 78 | }, 79 | handleClick(){ 80 | this.setState({enabler: false}) 81 | }, 82 | render(){ 83 | return( 84 |
85 |
86 |
87 |
88 | 89 |
Place type
90 | 91 |
92 |
93 | 94 |
Bedrooms
95 | 96 |
97 |
98 | 99 |
Baths
100 | 101 |
102 |
103 | 104 |
Location
105 | 106 |
107 |
108 | 109 |
Amenities
110 | 111 |
112 |
113 | 114 |
Shared spaces
115 | 116 |
117 |
118 |
119 | 120 |
121 |
122 |
123 |
124 |
125 |
126 |
How many guests can your place accommodate?
127 |
128 | 129 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 |
145 |
146 |
How many beds can guests use?
147 |
148 | 149 |
150 |
151 | 152 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 |
162 |
163 |
164 |
How many guests can stay?
165 |
166 | 167 |
168 |
169 |
170 | 171 |
172 |
173 | 174 | 178 | 179 |
180 |
181 | 182 | 188 | 189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | 197 |
198 |
199 | 200 | 201 | 202 |
203 |
204 |
The number and type of beds you have determines how many guests can stay comfortably
205 |
206 |
207 | 208 |
209 |
210 |
211 |
212 | ) 213 | } 214 | 215 | 216 | }) 217 | -------------------------------------------------------------------------------- /src/become-a-host/steps/stepOne/Location.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | const styles = { 5 | main: { 6 | backgroundImage: 'url(' + 'http://static1.squarespace.com/static/55fa2918e4b08929c4af4bfa/5707588bab48de09bc427fb3/570758ece707eb820b407d6e/1460099353424/Renan+Ozturk+insta+photo+%281+of+1%29-39.jpg' + ')', 7 | backgroundSize: 'cover', 8 | position: "fixed", 9 | top: 67, 10 | bottom: 0, 11 | width: '100%', 12 | } 13 | } 14 | 15 | 16 | export default React.createClass({ 17 | render(){ 18 | return( 19 |
20 |
21 | 22 |
Under Construction 😲
23 | 24 |
25 |
26 | ) 27 | } 28 | }) 29 | -------------------------------------------------------------------------------- /src/become-a-host/steps/stepOne/Room.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import Checkbox from 'material-ui/Checkbox'; 5 | import DropDownMenu from 'material-ui/DropDownMenu'; 6 | import MenuItem from 'material-ui/MenuItem'; 7 | import FlatButton from 'material-ui/FlatButton'; 8 | import RaisedButton from 'material-ui/RaisedButton'; 9 | import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton'; 10 | 11 | import Lightbulb from 'material-ui/svg-icons/action/lightbulb-outline'; 12 | import Home from 'material-ui/svg-icons/action/home'; 13 | import Seat from 'material-ui/svg-icons/action/event-seat'; 14 | import Hotel from 'material-ui/svg-icons/maps/hotel'; 15 | import OpenCircle from 'material-ui/svg-icons/image/panorama-fish-eye'; 16 | import SelectedCircle from 'material-ui/svg-icons/image/adjust'; 17 | 18 | require ("../steps.scss") 19 | 20 | 21 | 22 | const styles = { 23 | block: { 24 | maxWidth: 250, 25 | }, 26 | checkbox: { 27 | marginBottom: 16, 28 | }, 29 | customWidth: { 30 | width: 320, 31 | marginTop: '3px', 32 | border: "none", 33 | }, 34 | dropDown: { 35 | backgroundColor: "#484848", 36 | fontFamily: "Roboto", 37 | width: "100%", 38 | border: "none", 39 | marginBottom: "1vh", 40 | borderRadius: "3px", 41 | }, 42 | radio: { 43 | display: "flex", 44 | justifyContent: "space-between", 45 | width: "270px", 46 | borderBottom: "1px solid #E6E6E6", 47 | height: "65px", 48 | padding: "20px 5px", 49 | paddingRight: "15px", 50 | }, 51 | placetypeIcon: { 52 | color: "#E6E6E6", 53 | borderBottom: "1px solid #E6E6E6", 54 | height: "65px", 55 | padding: "10px ", 56 | width: '48px' 57 | } 58 | }; 59 | 60 | export default React.createClass({ 61 | getInitialState() { 62 | return { 63 | value: 1, 64 | enabler: true 65 | } 66 | }, 67 | handleChange(event, index, value){ 68 | this.setState({value}) 69 | }, 70 | handleClick(){ 71 | this.setState({enabler: false}) 72 | }, 73 | render(){ 74 | return( 75 |
76 |
77 |
78 |
79 | 80 |
Place type
81 | 82 |
83 |
84 | 85 |
Bedrooms
86 | 87 |
88 |
89 | 90 |
Baths
91 | 92 |
93 |
94 | 95 |
Location
96 | 97 |
98 |
99 | 100 |
Amenities
101 | 102 |
103 |
104 | 105 |
Shared spaces
106 | 107 |
108 |
109 |
110 | 111 |
112 |
113 |
114 |
115 |
116 |
117 |
What kind of place are you listing?
118 |
119 | 120 |
121 | 122 | 123 | 124 |
125 |
126 |
127 | 128 | 129 | 134 | 139 | 144 | 145 | 146 |
147 |
148 |
149 |
What type of property is this?
150 |
151 | 152 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 |
188 |
189 |
190 | 191 |
192 |
193 | 194 | 198 | 199 |
200 |
201 | 202 | 210 | 211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | 219 |
220 |
221 | 222 | 223 | 224 |
225 |
226 |
Entire Place
227 |
Guests will rent the entire place. Includes in-law units.
228 |
229 |
230 |
Private Room
231 |
Guests share some spaces but they’ll have their own private room for sleeping.
232 |
233 |
234 |
Shared Room
235 |
Guests don’t have a room to themselves.
236 |
237 |
238 | 239 |
240 |
241 |
242 |
243 | ) 244 | } 245 | 246 | 247 | }) 248 | -------------------------------------------------------------------------------- /src/become-a-host/steps/stepOne/Spaces.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import Checkbox from 'material-ui/Checkbox'; 5 | import FlatButton from 'material-ui/FlatButton'; 6 | import RaisedButton from 'material-ui/RaisedButton'; 7 | import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton'; 8 | 9 | // import ChequeBox from '../../ChequeBox.svg'; 10 | // import ChequedBox from '../../ChequedBox.svg'; 11 | import Lightbulb from 'material-ui/svg-icons/action/lightbulb-outline'; 12 | 13 | require ("../steps.scss") 14 | 15 | 16 | 17 | 18 | const styles = { 19 | box: { 20 | width: 320, 21 | height: 70, 22 | fontSize: 18, 23 | } 24 | }; 25 | 26 | export default React.createClass({ 27 | render(){ 28 | return( 29 |
30 |
31 |
32 |
33 | 34 |
Place type
35 | 36 |
37 |
38 | 39 |
Bedrooms
40 | 41 |
42 |
43 | 44 |
Baths
45 | 46 |
47 |
48 | 49 |
Location
50 | 51 |
52 |
53 | 54 |
Amenities
55 | 56 |
57 |
58 | 59 |
Shared spaces
60 | 61 |
62 |
63 |
64 | 65 |
66 |
67 |
68 |
69 |
70 |
71 |
What amenitites do you offer?
72 | 73 |
74 | 79 | 84 | 89 | 94 | 99 | 104 | 109 | 114 |
115 |
116 |
117 | 118 |
119 |
120 | 121 |
122 |
123 | 124 | 128 | 129 |
130 |
131 | 132 | 138 | 139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | 147 |
148 |
149 | 150 | 151 | 152 |
153 |
154 |
155 | Spaces should be on the property. Don’t include laundromats or nearby places that aren’t 156 | part of your property. If it’s OK with your neighbors, you can include a pool, hot tub, 157 | or other shared space. 158 |
159 |
160 |
161 | 162 |
163 |
164 |
165 |
166 | ) 167 | } 168 | 169 | 170 | }) 171 | -------------------------------------------------------------------------------- /src/become-a-host/steps/stepTwo/Highlights.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | 4 | export default React.createClass({ 5 | render(){ 6 | return( 7 |
Hi 8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 | ) 18 | } 19 | 20 | 21 | 22 | }) 23 | -------------------------------------------------------------------------------- /src/become-a-host/steps/steps.scss: -------------------------------------------------------------------------------- 1 | $light: #FAFAFA; 2 | $medium: #E6E6E6; 3 | $dark: #A2A2A2; 4 | $darkest: #4B4B4B; 5 | 6 | 7 | .room-parent-container { 8 | font-family: 'Roboto'; 9 | color: #4B4B4B; 10 | } 11 | .active-tab { 12 | padding: 12px 14px; 13 | font-size: 15px; 14 | width: 16.666666666666668%; 15 | max-width: 100%; 16 | background-color: #E6E6E6; 17 | overflow: hidden; 18 | text-overflow: ellipsis; 19 | outline: 1px solid #dce0e0; 20 | float: left; 21 | } 22 | .inactive-tab { 23 | padding: 12px 14px; 24 | font-size: 15px; 25 | width: 16.666666666666668%; 26 | max-width: 100%; 27 | background-color: #FAFAFA; 28 | outline: 1px solid #dce0e0; 29 | float: left; 30 | text-overflow: ellipsis; 31 | } 32 | .inactive-tab:hover { 33 | background-color: #F0F0F0; 34 | cursor: pointer; 35 | } 36 | .content { 37 | margin-top: 15px; 38 | } 39 | .form-side { 40 | background-color: white; 41 | position: fixed; 42 | left: 0; 43 | bottom: 0; 44 | top: 90px; 45 | } 46 | 47 | .instruction-side { 48 | position: fixed; 49 | left: 55%; 50 | top: 130px; 51 | } 52 | .form-container { 53 | float: none; 54 | padding: 20px; 55 | margin: 0 0 0 0; 56 | .form-title-large { 57 | color: $darkest; 58 | font-size: 24px; 59 | margin-bottom: 20px; 60 | width: 363px; 61 | word-wrap: break-word; 62 | } 63 | .form-title-medium { 64 | color: $dark; 65 | font-size: 18px; 66 | font-weight: 300; 67 | } 68 | } 69 | .button-container { 70 | width: 320px; 71 | border: 1px solid $medium; 72 | border-radius: 4px; 73 | margin-bottom: 30px; 74 | display: flex; 75 | flex-direction: row; 76 | .placetype-icon { 77 | display: flex; 78 | justify-content: space-around; 79 | flex-direction: column; 80 | width: 50px; 81 | } 82 | } 83 | .drop-down-menu { 84 | border: 1px solid $medium; 85 | border-radius: 4px; 86 | height: 65px; 87 | width: 320px; 88 | margin-top: 4px; 89 | } 90 | .step-nav { 91 | position: fixed; 92 | z-index: 111; 93 | bottom: 0px; 94 | border-top: 1px solid $medium; 95 | .back-next { 96 | margin-top: 20px; 97 | } 98 | } 99 | .incrementer { 100 | @extend .drop-down-menu; 101 | padding: 22px 0 0 20px; 102 | .increment-label { 103 | color: $dark; 104 | padding-left: 6px; 105 | } 106 | .increment-number { 107 | color: $medium; 108 | } 109 | .subtract { 110 | background: none; 111 | border: none; 112 | border-left: 1px solid $medium; 113 | font-size: 42px; 114 | font-weight: 300; 115 | width: 63px; 116 | margin-top: -22px; 117 | color: $medium; 118 | } 119 | .add { 120 | @extend .subtract; 121 | color: $dark; 122 | } 123 | } 124 | .clicker { 125 | -webkit-appearance: none; 126 | background-color: #fafafa; 127 | border: 1px solid #cacece; 128 | box-shadow: 0 1px 2px rgba(0,0,0,0.05), inset 0px -15px 10px -12px rgba(0,0,0,0.05); 129 | padding: 9px; 130 | border-radius: 3px; 131 | display: inline-block; 132 | position: relative; 133 | } 134 | .note-container { 135 | max-width: 306px; 136 | padding: 26px; 137 | margin: 50px 0 0 26px; 138 | background-color: white; 139 | border: 1px solid $medium; 140 | border-radius: 3px; 141 | 142 | .note-title { 143 | color: $darkest; 144 | } 145 | .note-content { 146 | color: $dark; 147 | margin-top: 3px; 148 | letter-spacing: 1px; 149 | font-size: 14px; 150 | line-height: 22px; 151 | font-weight: 300; 152 | } 153 | } 154 | 155 | .next-btn { 156 | text-align: right; 157 | } 158 | 159 | .back-btn { 160 | 161 | } 162 | 163 | @media (min-width: 768px) { 164 | .instruction-side { 165 | margin-top: 5px; 166 | } 167 | .form-container { 168 | float: right; 169 | margin-right: 50px; 170 | margin-top: 30px; 171 | } 172 | .form-side { 173 | top: 140px; 174 | width: 55%; 175 | } 176 | .step-nav { 177 | float: right; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/common.js: -------------------------------------------------------------------------------- 1 | module.exports = "Common"; 2 | -------------------------------------------------------------------------------- /src/date-range-picker/DateRangePickerGmapPage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import axios from 'axios'; 3 | import moment from 'moment'; 4 | 5 | import { DateRangePicker } from 'react-dates'; 6 | 7 | class DateRangePickerGmapPage extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | focusedInput: null, 12 | // startDate: moment('2016-10-10'), 13 | // endDate: moment('2016-10-30'), 14 | searchVal: 'Manila', 15 | numGuests: 1, 16 | }; 17 | 18 | this.onDatesChange = this.onDatesChange.bind(this); 19 | this.onFocusChange = this.onFocusChange.bind(this); 20 | this.guestNumSelected = this.guestNumSelected.bind(this); 21 | } 22 | 23 | onDatesChange({ startDate, endDate }) { 24 | console.log('startDate: ', startDate); 25 | console.log('startDate: ', endDate); 26 | 27 | this.setState({ startDate, endDate }); 28 | 29 | axios.post('/search',{ 30 | searchVal: this.props.location, 31 | startDate: this.state.startDate.format('MM/DD/YYYY'), 32 | endDate: this.state.endDate.format('MM/DD/YYYY'), 33 | numGuests: this.state.numGuests 34 | }).then(response =>{ 35 | console.log('OOMFGGGFGGG ', response); 36 | this.props.renderMap(response.data); 37 | }) 38 | } 39 | 40 | onFocusChange(focusedInput) { 41 | this.setState({ focusedInput }); 42 | } 43 | 44 | guestNumSelected(e){ 45 | console.log(e.target.value); 46 | const x = e.target.value.match(/\d\d?/) 47 | 48 | this.setState({numGuests: parseInt(x[0])}); 49 | 50 | axios.post('/search',{ 51 | searchVal: this.props.location, 52 | startDate: this.state.startDate.format('MM/DD/YYYY'), 53 | endDate: this.state.endDate.format('MM/DD/YYYY'), 54 | numGuests: this.state.numGuests, 55 | room_types: this.props.roomTypeSelected, 56 | price_min: this.props.values[0], 57 | price_max: this.props.values[1], 58 | }).then(response =>{ 59 | this.props.renderMap(response.data); 60 | }) 61 | } 62 | 63 | render() { 64 | const { focusedInput, startDate, endDate } = this.state; 65 | 66 | const selectGenerator = () =>{ 67 | let arr = []; 68 | for(let i = 1; i <= 16; i++){ 69 | 70 | let x = 0; 71 | if(i === 1){ 72 | x = i + ' Guest'; 73 | } else { 74 | x = i + ' Guests'; 75 | } 76 | 77 | if(i == 16){ 78 | x = x.replace('16','16+'); 79 | } 80 | 81 | arr.push(x); 82 | } 83 | return arr 84 | } 85 | 86 | const roomsArray = selectGenerator(); 87 | 88 | const roomSelection = roomsArray.map((currentVal,i)=>{ 89 | return 90 | }) 91 | 92 | return ( 93 |
94 |
95 | 96 | 104 | 107 | 108 | 109 | 110 |
111 | ); 112 | } 113 | } 114 | 115 | export default DateRangePickerGmapPage; 116 | -------------------------------------------------------------------------------- /src/date-range-picker/SearchBar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import axios from 'axios'; 3 | import moment from 'moment'; 4 | 5 | import { DateRangePicker } from 'react-dates'; 6 | 7 | class SearchBar extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | focusedInput: null, 12 | // startDate: moment('2016-09-10'), 13 | // endDate: moment('2016-09-30'), 14 | searchVal: 'Manila', 15 | numGuests: null, 16 | }; 17 | 18 | this.onDatesChange = this.onDatesChange.bind(this); 19 | this.onFocusChange = this.onFocusChange.bind(this); 20 | this.onSubmitSearch = this.onSubmitSearch.bind(this); 21 | this.onTyping = this.onTyping.bind(this); 22 | this.guestNumSelected = this.guestNumSelected.bind(this); 23 | } 24 | 25 | onDatesChange({ startDate, endDate }) { 26 | this.setState({ startDate, endDate }); 27 | } 28 | 29 | onFocusChange(focusedInput) { 30 | console.log('focusedInput: ',focusedInput) 31 | this.setState({ focusedInput }); 32 | } 33 | 34 | onSubmitSearch(e) { 35 | console.log(this.state.startDate) 36 | console.log(this.state.endDate) 37 | 38 | axios.post('/search',{ 39 | searchVal: this.state.searchVal, 40 | startDate: this.state.startDate.format('MM/DD/YYYY'), 41 | endDate: this.state.endDate.format('MM/DD/YYYY'), 42 | numGuests: this.state.numGuests, 43 | room_types: [], 44 | }).then(response =>{ 45 | console.log('response from server: ', response) 46 | window.location.href = '/search-results'; 47 | }) 48 | 49 | e.preventDefault(); 50 | } 51 | 52 | onTyping(e){ 53 | console.log(e.target.value); 54 | this.setState({searchVal: e.target.value}); 55 | } 56 | 57 | guestNumSelected(e){ 58 | console.log(e.target.value); 59 | const x = e.target.value.match(/\d\d?/) 60 | 61 | this.setState({numGuests: parseInt(x[0])}); 62 | // this.setState({}) 63 | } 64 | 65 | 66 | render() { 67 | const { focusedInput, startDate, endDate } = this.state; 68 | 69 | const selectGenerator = () =>{ 70 | let arr = []; 71 | for(let i = 1; i <= 16; i++){ 72 | 73 | let x = 0; 74 | if(i === 1){ 75 | x = i + ' Guest'; 76 | } else { 77 | x = i + ' Guests'; 78 | } 79 | 80 | if(i == 16){ 81 | x = x.replace('16','16+'); 82 | } 83 | 84 | arr.push(x); 85 | } 86 | return arr 87 | } 88 | 89 | const roomsArray = selectGenerator(); 90 | 91 | const roomSelection = roomsArray.map((currentVal,i)=>{ 92 | return 93 | }) 94 | 95 | return ( 96 |
97 |
98 | 99 | 107 | 110 | 111 | 112 | 113 | 114 |
115 | ); 116 | } 117 | } 118 | 119 | export default SearchBar; 120 | -------------------------------------------------------------------------------- /src/footer/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import DropDownMenu from 'material-ui/DropDownMenu'; 4 | import MenuItem from 'material-ui/MenuItem'; 5 | require ("./footer.scss") 6 | 7 | const styles ={ 8 | width: "100vw", 9 | backgroundColor: "#2B2D2E", 10 | fontFamily: "Roboto", 11 | logoOverlay: { 12 | backgroundImage: 'url('+ 'https://a0.muscache.com/airbnb/static/footer/background-317dd7c2cb678ddbdb0a983d511cb9a0.png' + ')', 13 | backgroundSize: "contain", 14 | backgroundRepeat: "repeat", 15 | height: "100%", 16 | width: "100%" 17 | }, 18 | siteNav: { 19 | height: "60%", 20 | paddingTop: "6vh", 21 | display: "flex", 22 | flexDirection: "row", 23 | color: "white", 24 | fontWeight: "300", 25 | fontSize: 13, 26 | lineHeight: "20px", 27 | listStyleType: "none", 28 | }, 29 | h6: { 30 | fontSize: 15, 31 | fontWeight: "400", 32 | marginBottom: "1.5vh", 33 | }, 34 | dropDown: { 35 | backgroundColor: "#484848", 36 | fontFamily: "Roboto", 37 | width: "100%", 38 | border: "none", 39 | marginBottom: "1vh", 40 | borderRadius: "3px", 41 | }, 42 | social: { 43 | height: "20%", 44 | textAlign: "center", 45 | marginLeft: "auto", 46 | marginRight: "auto", 47 | }, 48 | icons: { 49 | display: "flex", 50 | flexDirection: "row", 51 | marginLeft: "auto", 52 | marginRight: "auto", 53 | justifyContent: "space-between", 54 | textDecoration: "none", 55 | }, 56 | listItem: { 57 | display: "flex", 58 | justifyContent: "center", 59 | alignItems: "center", 60 | width: "34px", 61 | height: "34px", 62 | border: "1px solid rgba(255, 255, 255, .2)", 63 | borderRadius: "50%", 64 | color: "white", 65 | padding: "0", 66 | } 67 | } 68 | 69 | export default React.createClass({ 70 | render(){ 71 | return( 72 |
73 |
74 |
75 | 76 |
79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |
97 |
98 |
99 |
102 | 103 |
104 | 147 |
148 |
149 |
Join Us On
150 |
151 |
152 |
153 | 154 | 155 | 156 |
157 |
158 | 159 | 160 | 161 |
162 |
163 | 164 | 165 | 166 |
167 |
168 | 169 | 170 | 171 |
172 |
173 | 174 | 175 | 176 |
177 |
178 | 179 | 180 | 181 |
182 |
183 | 184 | 185 | 186 |
187 |
188 |
189 |
190 | 191 | Airbnb, Inc. 192 |
193 |
194 |
195 |
196 | ) 197 | } 198 | }) 199 | -------------------------------------------------------------------------------- /src/footer/footer.scss: -------------------------------------------------------------------------------- 1 | li:hover { 2 | color: rgba(255, 255, 255, .6); 3 | cursor: pointer; 4 | } 5 | .footer-main { 6 | height: 340px; 7 | } 8 | #site-nav { 9 | display: none; 10 | } 11 | #drop-downs { 12 | width: 80%; 13 | } 14 | #join { 15 | display: none; 16 | } 17 | #icon-container { 18 | width: 290px; 19 | margin-right: auto; 20 | margin-left: auto; 21 | } 22 | #social-media { 23 | border-top: none !important; 24 | width: 100% !important; 25 | } 26 | 27 | @media (min-width: 767px) { 28 | .footer-main { 29 | height: 59vh; 30 | } 31 | #site-nav { 32 | display: block; 33 | } 34 | #join { 35 | display: block; 36 | } 37 | #social-media { 38 | border-top: 1px solid rgba(255, 255, 255, .2) !important; 39 | width: 75% !important; 40 | } 41 | #icon-container { 42 | width: 390px; 43 | margin-left: auto; 44 | margin-right: auto; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/home/BelongAnywhere.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Slider from 'react-slick'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import FlatButton from 'material-ui/FlatButton'; 5 | import LeftNavButton from './LeftNavButton.js'; 6 | import RightNavButton from './RightNavButton.js'; 7 | 8 | const styles ={ 9 | width: "100%", 10 | first: { 11 | backgroundImage: 'url(' + 'https://a2.muscache.com/airbnb/static/homepages/belong-vid-b5b9b5ff3b53a7a4229d4acde53fb161.jpg' + ')', 12 | backgroundSize: "cover", 13 | height: '74vh', 14 | }, 15 | firstText: { 16 | width: "60vw", 17 | marginLeft: "auto", 18 | marginRight: "auto", 19 | marginTop: "22vh", 20 | textAlign: "center", 21 | display: "flex", 22 | flexDirection: "column", 23 | color: "white", 24 | }, 25 | second: { 26 | backgroundImage: 'url(' + 'https://a0.muscache.com/airbnb/static/homepages/belo-vid-078cd6a63626517f9294598ceda49ee5.jpg' + ')', 27 | backgroundSize: "cover", 28 | height: '74vh', 29 | }, 30 | third: { 31 | backgroundColor: "#FFB400", 32 | height: '74vh', 33 | }, 34 | fourth: { 35 | backgroundColor: "#FFB400", 36 | backgroundImage: 'url(' + 'https://a2.muscache.com/airbnb/static/homepages/vacation-rentals-banner-f9a857d36e05fa6dff10893587085326.png' + ')', 37 | backgroundSize: "cover", 38 | height: '74vh', 39 | }, 40 | } 41 | 42 | export default React.createClass({ 43 | render: function () { 44 | var settings = { 45 | nextArrow: , 46 | prevArrow: , 47 | infinite: true, 48 | speed: 500, 49 | slidesToShow: 1, 50 | slidesToScroll: 1, 51 | }; 52 | return ( 53 | 54 |
55 |
56 |
BELONG ANYWHERE
57 |
See how Airbnb hosts create a sense of belonging around the world
58 |
59 | 60 | 61 | 62 |
63 |
64 |
65 |
66 |
67 |
INTRODUCING THE BÉLO
68 |
The story of a symbol of belonging
69 |
70 |
71 |
72 |
73 | 74 |
75 | 76 |
77 | Make Airbnb yours 78 | Create your Symbol, Tell your Story 79 |
80 |
81 |
82 |
83 |
84 |
YOUR HOME,
EVERYWHERE
85 |
On Airbnb, every vacation rental fells like home. Find everything
from luxury villas to family friendly apartments
86 | 87 |
88 |
89 |
90 |
91 |
92 | ); 93 | } 94 | }); 95 | -------------------------------------------------------------------------------- /src/home/ExploreWorld.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const styles ={ 4 | fontFamily: "Roboto", 5 | h2: { 6 | fontSize: '32px', 7 | color: 'white', 8 | }, 9 | price: { 10 | backgroundColor: "rgba(45,45,45,0.9)", 11 | position: "absolute", 12 | bottom: "30px", 13 | left: "0", 14 | color: "white", 15 | fontSize: "22px", 16 | fontWeight: "300", 17 | padding: "8px 19px", 18 | }, 19 | hostPic: { 20 | height: "60px", 21 | width: "60px", 22 | borderRadius: "50%", 23 | border: "2px solid white", 24 | }, 25 | hostName: { 26 | marginTop: "12px", 27 | color: "white", 28 | fontSize: "22px", 29 | fontWeight: "300", 30 | }, 31 | hostPlace: { 32 | color: "white", 33 | fontSize: "13px", 34 | fontWeight: "300", 35 | }, 36 | table: { 37 | display: "table", 38 | position: "relative", 39 | width: "100%", 40 | height: "100%", 41 | }, 42 | tableCell: { 43 | display: "table-cell", 44 | verticalAlign: "middle", 45 | textAlign: "center", 46 | boxSizing: "border-box", 47 | }, 48 | title: { 49 | marginTop: "4vh", 50 | textAlign: "center", 51 | fontWeight: "500", 52 | fontSize: "32px", 53 | color: "#484848", 54 | }, 55 | subtitle: { 56 | marginBottom: "4vh", 57 | fontSize: "16px", 58 | textAlign: "center", 59 | color: "#484848", 60 | }, 61 | paris: { 62 | backgroundImage: 'url(' + 'https://a0.muscache.com/ic/discover/397?interpolation=lanczos-none&output-format=jpg&output-quality=70&v=33b4f2&downsize=655px:326px' + ')', 63 | backgroundSize: 'cover', 64 | position: 'relative', 65 | height: '344px', 66 | }, 67 | anna: { 68 | backgroundImage: 'url(' + 'https://a1.muscache.com/im/pictures/15273358/d7329e9a_original.jpg?aki_policy=x_medium' + ')', 69 | backgroundSize: 'cover', 70 | height: '344px', 71 | backgroundPosition: "center", 72 | }, 73 | newYork: { 74 | backgroundImage: 'url(' + 'https://a1.muscache.com/ic/discover/84?interpolation=lanczos-none&output-format=jpg&output-quality=70&v=33b4f2&downsize=326px:326px' + ')', 75 | backgroundSize: 'cover', 76 | height: '344px', 77 | }, 78 | rome: { 79 | backgroundImage: 'url(' + 'https://a0.muscache.com/ic/discover/290?interpolation=lanczos-none&output-format=jpg&output-quality=70&v=33b4f2&downsize=326px:326px' + ')', 80 | backgroundSize: 'cover', 81 | height: '344px', 82 | }, 83 | seattle: { 84 | backgroundImage: 'url(' + 'https://a0.muscache.com/ic/pictures/discovery/attribute_photos/relaxation_1x1.jpg?interpolation=lanczos-none&output-format=jpg&output-quality=70&size=large_cover&downsize=326px:326px&v=6' + ')', 85 | backgroundSize: 'cover', 86 | backgroundPosition: "center", 87 | height: '344px', 88 | }, 89 | torsten: { 90 | backgroundImage: 'url(' + 'https://a2.muscache.com/im/pictures/45344186/0c74c9b7_original.jpg?aki_policy=x_medium' + ')', 91 | backgroundSize: 'cover', 92 | height: '344px', 93 | }, 94 | london: { 95 | backgroundImage: 'url(' + 'https://a2.muscache.com/ic/discover/42?interpolation=lanczos-none&output-format=jpg&output-quality=70&v=33b4f2&downsize=655px:326px' + ')', 96 | backgroundSize: 'cover', 97 | height: '344px', 98 | }, 99 | venice: { 100 | backgroundImage: 'url(' + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR2Oxn_aoucq9sxC_4IdnDlJEFRWuZTwgdo3SKQl1STWTjuv9gr' + ')', 101 | backgroundSize: 'cover', 102 | height: '344px', 103 | }, 104 | portland: { 105 | backgroundImage: 'url(' + 'https://static.squarespace.com/static/53019bf4e4b0c6ad9e40d7b4/t/5301b274e4b016fa7cab900f/1392620148313/portland.jpg' + ')', 106 | backgroundSize: 'cover', 107 | height: '344px', 108 | }, 109 | slc: { 110 | backgroundImage: 'url(' + 'https://a0.muscache.com/ic/pictures/discovery/attribute_photos/hiking_2x1.jpg?interpolation=lanczos-none&output-format=jpg&output-quality=70&size=large_cover&downsize=655px:326px&v=6' + ')', 111 | backgroundSize: 'cover', 112 | height: '344px', 113 | }, 114 | } 115 | 116 | export default React.createClass({ 117 | render(){ 118 | return( 119 |
120 |
Explore the world
121 |
See where people are traveling, all around the world.
122 | 123 |
124 | 135 | 151 | 162 | 173 | 184 | 200 | 211 | 222 | 233 | 244 |
245 |
246 | ) 247 | } 248 | }); 249 | -------------------------------------------------------------------------------- /src/home/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import HomeSearchBar from './Home-search-bar.js'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import RaisedButton from 'material-ui/RaisedButton'; 5 | 6 | 7 | const photo = { 8 | hero: 'https://www.airbnb.com/static/engagement/four-people-bike-99597e51f3a69bfa567999e79eb51109.jpg', 9 | vid: 'https://a0.muscache.com/airbnb/static/P1F1.jpg', 10 | } 11 | 12 | const style ={ 13 | margin: 12, 14 | heroImage: { 15 | backgroundImage: 'url('+ photo.vid +')', 16 | backgroundSize: 'cover', 17 | backgroundRepeat: 'no-repeat', 18 | width: '100vw', 19 | padding: 0, 20 | 21 | }, 22 | upperHalf:{ 23 | color: '#fff', 24 | height: '81%', 25 | display: 'flex', 26 | flexDirection: 'column', 27 | justifyContent: 'center', 28 | alignItems: 'center', 29 | paddingTop: '70px', 30 | }, 31 | searchContainer:{ 32 | backgroundColor: 'rgba(0,0,0,0.6)', 33 | height: '19%', 34 | width: '100vw', 35 | display: 'flex', 36 | alignItems: 'center', 37 | justifyContent: 'center' 38 | 39 | 40 | } 41 | 42 | 43 | } 44 | 45 | export default React.createClass({ 46 | render(){ 47 | return( 48 | 68 | ) 69 | } 70 | }); 71 | -------------------------------------------------------------------------------- /src/home/Home-search-bar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import moment from 'moment'; 4 | 5 | import SearchBar from '../date-range-picker/SearchBar.jsx'; 6 | require('./_datepicker.scss'); 7 | 8 | var HomeSearchBar = React.createClass({ 9 | 10 | render(){ 11 | return( 12 |
13 | 14 |
15 | ) 16 | } 17 | 18 | }) 19 | 20 | export default HomeSearchBar 21 | -------------------------------------------------------------------------------- /src/home/Home.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import Header from "./Header"; 3 | import HostCarousel from "./HostCarousel"; 4 | import JustForWknd from "./JustForWknd"; 5 | import ExploreWorld from "./ExploreWorld"; 6 | import BelongAnywhere from "./BelongAnywhere"; 7 | import OurCommunity from "./OurCommunity"; 8 | import Footer from '../footer/Footer'; 9 | require('./home.component.scss'); 10 | 11 | import HomeSearchBar from './Home-search-bar.js'; 12 | 13 | 14 | class Home extends Component { 15 | render() { 16 | return ( 17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 | ); 27 | } 28 | } 29 | 30 | export default Home; 31 | -------------------------------------------------------------------------------- /src/home/HostCarousel.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import FlatButton from 'material-ui/FlatButton'; 4 | import Slider from 'react-slick'; 5 | 6 | const style ={ 7 | margin: '12', 8 | words: { 9 | backgroundColor: '#fff', 10 | height: '360px', 11 | color:'#484848', 12 | display: 'flex', 13 | alignItems: 'center', 14 | justifyContent: 'center', 15 | flexDirection: 'column' 16 | }, 17 | 18 | } 19 | 20 | 21 | export default React.createClass({ 22 | render(){ 23 | var settings = { 24 | infinite: true, 25 | speed: 500, 26 | accessibility: false, 27 | arrows: false, 28 | autoplay: true, 29 | autoplaySpeed: 7000, 30 | fade: true 31 | }; 32 | return( 33 | 34 | 35 |
36 | 37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 |
Hosting opens up a world of opportunity
50 |

Earn money sharing your extra space with travelers.

51 | 52 | 53 | 54 | 55 | 56 |
57 |
58 | 59 | 60 | 61 | 62 |
63 | 64 |
65 | 66 | 67 | ) 68 | } 69 | }); 70 | -------------------------------------------------------------------------------- /src/home/JustForWknd.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import FlatButton from 'material-ui/FlatButton'; 4 | import Slider from 'react-slick'; 5 | 6 | 7 | const styles ={ 8 | fontFamily: "Roboto", 9 | h2: { 10 | fontSize: '32px', 11 | color: 'white', 12 | }, 13 | table: { 14 | display: "table", 15 | position: "relative", 16 | width: "100%", 17 | height: "100%", 18 | }, 19 | tableCell: { 20 | display: "table-cell", 21 | verticalAlign: "middle", 22 | textAlign: "center", 23 | boxSizing: "border-box", 24 | }, 25 | title: { 26 | marginTop: "4vh", 27 | textAlign: "center", 28 | fontWeight: "500", 29 | fontSize: "32px", 30 | color: "#484848", 31 | }, 32 | subtitle: { 33 | marginBottom: "4vh", 34 | fontSize: "16px", 35 | textAlign: "center", 36 | color: "#484848", 37 | }, 38 | vegas: { 39 | backgroundImage: 'url(' + 'https://a2.muscache.com/ic/discover/591?interpolation=lanczos-none&output-format=jpg&output-quality=70&v=33b4f2&downsize=675px:675px' + ')', 40 | backgroundSize: 'cover', 41 | position: 'relative', 42 | height: '344px', 43 | }, 44 | losAngles: { 45 | backgroundImage: 'url(' + 'https://a1.muscache.com/ic/discover/2892?interpolation=lanczos-none&output-format=jpg&output-quality=70&v=33b4f2&downsize=675px:675px' + ')', 46 | backgroundSize: 'cover', 47 | height: '344px', 48 | }, 49 | sanDiego: { 50 | backgroundImage: 'url(' + 'https://a0.muscache.com/ic/discover/1442?interpolation=lanczos-none&output-format=jpg&output-quality=70&v=33b4f2&crop=0.67xw:1xh;*,*&downsize=675px:675px' + ')', 51 | backgroundSize: 'cover', 52 | height: '344px', 53 | }, 54 | } 55 | 56 | 57 | 58 | export default React.createClass({ 59 | render(){ 60 | return( 61 |
62 |
Just for the Weekend
63 |
Discover new, inspiring places close to home.
64 | 65 | 66 |
67 |
68 | 69 |
70 |
71 |
Vegas
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | 80 |
81 |
82 |
Los Angles
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | 91 |
92 |
93 |
San Diego
94 |
95 |
96 |
97 |
98 |
99 |
100 | ) 101 | } 102 | }); 103 | -------------------------------------------------------------------------------- /src/home/LeftNavButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class LeftNavButton extends React.Component { 4 | render() { 5 | return ( 6 |
7 | 10 |
11 | ) 12 | } 13 | } 14 | 15 | export default LeftNavButton; 16 | -------------------------------------------------------------------------------- /src/home/OurCommunity.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const styles ={ 4 | fontFamily: "Roboto", 5 | color: "white", 6 | title: { 7 | margin: "5vh", 8 | textAlign: "center", 9 | fontFamily: "Roboto", 10 | color: "#484848", 11 | fontSize: "32px", 12 | fontWeight: "500", 13 | }, 14 | pictureContainer: { 15 | width: "100%", 16 | height: "62vh", 17 | display: "flex", 18 | flexDirection: "row", 19 | justifyContent: "space-around", 20 | marginBottom: "3vh", 21 | }, 22 | picture1: { 23 | height: "100%", 24 | width: "22.5vw", 25 | display: "flex", 26 | flexDirection: "column", 27 | justifyContent: "center", 28 | backgroundColor: "#009AAB", 29 | color: "white", 30 | textAlign: "center", 31 | }, 32 | biker: { 33 | marginTop: "35px", 34 | }, 35 | picture2: { 36 | backgroundImage: 'url(' + 'https://a1.muscache.com/airbnb/static/homepages/traveling-edebfe1eafd15383d4872876d41bd50e.jpg' + ')', 37 | backgroundSize: "cover", 38 | height: "100%", 39 | width: "22.5vw", 40 | display: "flex", 41 | color: "white", 42 | textAlign: "center", 43 | flexDirection: "column", 44 | 45 | }, 46 | traveling: { 47 | height: "35px", 48 | width: "75px", 49 | backgroundColor: "#007A87", 50 | color: "white", 51 | fontSize: "13px", 52 | display: "flex", 53 | alignSelf: "center", 54 | alignItems: "center", 55 | justifyContent: "center", 56 | }, 57 | Garry: { 58 | width: '80%', 59 | heigh: '20vh', 60 | paddingTop: "36vh", 61 | marginLeft: "auto", 62 | marginRight: "auto", 63 | }, 64 | picture3: { 65 | backgroundImage: 'url(' + 'https://a1.muscache.com/airbnb/static/homepages/business-56c80d9222a2e084253f33e893f8bd32.jpg' + ')', 66 | backgroundSize: "cover", 67 | height: "100%", 68 | width: "22.5vw", 69 | display: "flex", 70 | color: "white", 71 | textAlign: "center", 72 | flexDirection: "column", 73 | }, 74 | business: { 75 | height: "35px", 76 | width: "110px", 77 | backgroundColor: "#393C3D", 78 | color: "white", 79 | fontSize: "13px", 80 | display: "flex", 81 | alignSelf: "center", 82 | alignItems: "center", 83 | justifyContent: "center" 84 | }, 85 | forBusiness: { 86 | width: '95%', 87 | heigh: '20vh', 88 | paddingTop: "40vh", 89 | marginLeft: "auto", 90 | marginRight: "auto", 91 | }, 92 | picture4: { 93 | backgroundImage: 'url(' + 'https://a2.muscache.com/airbnb/static/homepages/hosting-74e04c88d4df9607cc3025401a43c665.jpg' + ')', 94 | backgroundSize: "cover", 95 | height: "100%", 96 | width: "22.5vw", 97 | display: "flex", 98 | color: "white", 99 | textAlign: "center", 100 | flexDirection: "column", 101 | }, 102 | hosting: { 103 | height: "35px", 104 | width: "70px", 105 | backgroundColor: "#7B0051", 106 | color: "white", 107 | fontSize: "13px", 108 | display: "flex", 109 | alignSelf: "center", 110 | alignItems: "center", 111 | justifyContent: "center" 112 | }, 113 | patricia: { 114 | width: '95%', 115 | height: '20vh', 116 | paddingTop: "40vh", 117 | marginLeft: "auto", 118 | marginRight: "auto", 119 | } 120 | 121 | } 122 | 123 | export default React.createClass({ 124 | render(){ 125 | return( 126 |
127 |
128 |
131 |
132 |
Our community
133 |
134 |
135 |
136 |
137 |
140 |
141 |
142 |
143 |
144 | 145 |
146 |
147 | biker 148 |
149 |
150 |
Make Airbnb yours
151 |
Create your symbol, Tell your story
152 |
153 |
154 |
155 |
156 |
Traveling
157 |
158 |
Garry & Lianne
159 |
Across an ocean or across town, Garry & Lianne are always in search of local experiences
160 |
Learn more about travel on Airbnb
161 |
162 |
163 |
164 |
165 |
Business Travel
166 |
167 |
Airbnb for Business
168 |
Feel at home, wherever your work takes you.
169 |
Get your team on Airbnb
170 |
171 |
172 |
173 |
174 |
Hosting
175 |
176 |
Patricia
177 |
A professional photographer, Patricia loves helping guests explore Shanghai's arts scene
178 |
Learn more about hosting on Airbnb
179 |
180 |
181 |
182 |
183 |
184 |
185 | ) 186 | } 187 | 188 | }) 189 | -------------------------------------------------------------------------------- /src/home/RightNavButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class RightNavButton extends React.Component { 4 | render() { 5 | return ( 6 |
7 | 10 |
11 | ) 12 | } 13 | } 14 | 15 | export default RightNavButton; 16 | -------------------------------------------------------------------------------- /src/home/home.component.scss: -------------------------------------------------------------------------------- 1 | .row { 2 | margin: 0; 3 | } 4 | #picture { 5 | position: relative; 6 | } 7 | #picture:hover > .overlay { 8 | width:100%; 9 | height:100%; 10 | position:absolute; 11 | background-color:#000; 12 | opacity:0.1; 13 | } 14 | .main-home-container { 15 | width: 100%; 16 | margin-bottom: 70px; 17 | } 18 | #social-media { 19 | border: none; 20 | } 21 | #explore-card-margin { 22 | margin-bottom: -30px !important; 23 | } 24 | .fullscreen-video-player { 25 | background-color: #000; 26 | height: 100%; 27 | left: 0; 28 | position: fixed; 29 | top: 0; 30 | -webkit-transition: opacity 800ms ease; 31 | -moz-transition: opacity 800ms ease; 32 | -o-transition: opacity 800ms ease; 33 | transition: opacity 800ms ease; 34 | width: 100%; 35 | z-index: -1001; 36 | } 37 | .belong-anywhere { 38 | display: none; 39 | } 40 | .our-community { 41 | display: none; 42 | } 43 | 44 | @media (max-width: 767px) { 45 | //TODO: make image shrink 46 | .profilePic{ 47 | // max-width: 661px; 48 | // max-height: 661px; 49 | } 50 | .heroImage{ 51 | height: 450px; 52 | } 53 | .homeCaro{ 54 | width: 425px; 55 | } 56 | 57 | } 58 | @media (min-width: 768px) { 59 | .main-home-container { 60 | width: 680px; 61 | margin-left: auto; 62 | margin-right: auto; 63 | } 64 | .heroImage{ 65 | height: 600px; 66 | } 67 | #explore-card-margin { 68 | margin-bottom: 30px !important; 69 | } 70 | .home-container{ 71 | margin-top: 70px; 72 | } 73 | .homeCaro{ 74 | width: 686px; 75 | } 76 | .belong-anywhere { 77 | display: block; 78 | } 79 | .our-community { 80 | display: block; 81 | } 82 | } 83 | @media (min-width: 1128px) { 84 | .main-home-container { 85 | width: 1050px; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/navbar/Navbar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Component} from 'react'; 3 | import { Link } from 'react-router' 4 | import { stack as Menu } from 'react-burger-menu'; 5 | import Radium from 'radium'; 6 | require ('./navbar.component.scss'); 7 | 8 | import LoginModal from './login-modal.js' 9 | 10 | let RadiumLink = Radium(Link); 11 | 12 | var styles = { 13 | bmBurgerButton: { 14 | position: 'absolute', 15 | width: '24px', 16 | height: '20px', 17 | left: '10px', 18 | top: '25px' 19 | }, 20 | bmBurgerBars: { 21 | background: '#ff5a5f' 22 | }, 23 | bmCrossButton: { 24 | height: '24px', 25 | width: '24px' 26 | }, 27 | bmCross: { 28 | background: '#bdc3c7' 29 | }, 30 | bmMenu: { 31 | background: '#373a47', 32 | padding: '2.5em 1.5em 0', 33 | fontSize: '1.15em' 34 | }, 35 | bmMorphShape: { 36 | fill: '#373a47' 37 | }, 38 | bmItemList: { 39 | color: '#b8b7ad', 40 | padding: '0.8em' 41 | }, 42 | bmOverlay: { 43 | background: 'rgba(0, 0, 0, 0.3)' 44 | } 45 | } 46 | 47 | //Code for the NavBar 48 | class Navbar extends React.Component { 49 | constructor(props){ 50 | super(props) 51 | } 52 | 53 | render = () => { 54 | return ( 55 | 56 |
57 | 58 | Home 59 | Become a Host 60 | Sign Up 61 | Login 62 | 63 | 64 |
65 | Become a Host 66 | Help 67 | Sign Up 68 | {/* Login */} 69 | {/* Login */} 70 | 71 |
72 | 73 |
74 | ); 75 | } 76 | 77 | }; 78 | 79 | export default Navbar; 80 | -------------------------------------------------------------------------------- /src/navbar/login-modal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Dialog from 'material-ui/Dialog'; 3 | import FlatButton from 'material-ui/FlatButton'; 4 | import RaisedButton from 'material-ui/RaisedButton'; 5 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 6 | import Divider from 'material-ui/Divider'; 7 | import Paper from 'material-ui/Paper'; 8 | import TextField from 'material-ui/TextField'; 9 | import axios from 'axios'; 10 | import { browserHistory } from 'react-router'; 11 | 12 | const style = { 13 | marginLeft: 20, 14 | width: '330px' 15 | }; 16 | 17 | const customContentStyle = { 18 | width: '400px', 19 | maxWidth: 'none', 20 | }; 21 | 22 | const pink = { 23 | color: '#FF5E63', 24 | borderColor: '#FF5E63' 25 | } 26 | 27 | const grey = { 28 | color: '#EDEFED', 29 | } 30 | 31 | export default class DialogExampleSimple extends React.Component { 32 | constructor(props){ 33 | super(props) 34 | this.state = { 35 | open: false, 36 | email: null, 37 | password: null, 38 | }; 39 | } 40 | 41 | handleOpen = () => { 42 | this.setState({open: true}); 43 | }; 44 | 45 | handleClose = () => { 46 | this.setState({open: false}); 47 | }; 48 | 49 | onEmail = (e) => { 50 | console.log(e.keyCode) 51 | this.setState({email: e.target.value}); 52 | } 53 | 54 | onPassword = (e) => { 55 | console.log(e.keyCode) 56 | this.setState({password: e.target.value}) 57 | } 58 | 59 | submitLogin = () => { 60 | console.log('browserHistory: ', browserHistory) 61 | this.setState({open: false}); 62 | 63 | axios.post('/login', { 64 | email: this.state.email, 65 | password: this.state.password 66 | }) 67 | .then(function (response, err) { 68 | if(err) { 69 | console.log(err) 70 | } 71 | console.log('response: ', response); 72 | 73 | browserHistory.push('/profile/'); 74 | }) 75 | } 76 | 77 | render() { 78 | const actions = [ 79 | , 85 | , 92 | ]; 93 | 94 | const form = 95 | 104 | 105 | 115 | 116 | 117 | 118 | return ( 119 | 120 |
121 | 122 | 130 | {form} 131 | 132 |
133 |
134 | ); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/navbar/navbar.component.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | background-color: #EDEFED; 4 | font-family: 'Roboto', sans-serif; 5 | font-size: 1em; 6 | line-height: 1.4; 7 | height: 100%; 8 | margin: 0; 9 | padding: 0; 10 | } 11 | 12 | a { 13 | text-decoration: none; 14 | color: inherit; 15 | } 16 | 17 | /* HEADER */ 18 | .header { 19 | z-index: 9999; 20 | height: 66px; 21 | line-height: 66px; 22 | color: #484848; 23 | background-color: #fff; 24 | } 25 | 26 | .header_logo { 27 | font-weight: 700; 28 | margin-left: 25px; 29 | } 30 | 31 | .air-logo { 32 | vertical-align: middle; 33 | } 34 | 35 | /* MENU */ 36 | .menu { 37 | float: right; 38 | } 39 | 40 | .menu a { 41 | padding: 0 10px; 42 | } 43 | 44 | .menu a:hover { 45 | color: #484848; 46 | } 47 | 48 | .become-a-host { 49 | border: 2px solid #dce0e0; 50 | margin-right: 10px; 51 | padding: 5px; 52 | } 53 | 54 | .left-border-menu { 55 | border-left: 1px solid #dce0e0; 56 | } 57 | 58 | .left-border-menu:hover { 59 | border-left: 1px solid #dce0e0; 60 | color: #484848; 61 | } 62 | 63 | /* Burger Menu */ 64 | .bm-burger-button{ 65 | display: none; 66 | } 67 | 68 | /* RESPONSIVE */ 69 | @media only screen and (max-width: 768px) { 70 | .menu { 71 | display: none; 72 | } 73 | 74 | .bm-burger-button{ 75 | display: block; 76 | } 77 | 78 | .air-logo { 79 | margin-left: 30px; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/profile/Inbox.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import ProfileDash from "./ProfileDash"; 3 | import {List, ListItem} from 'material-ui/List'; 4 | import Divider from 'material-ui/Divider'; 5 | import Subheader from 'material-ui/Subheader'; 6 | import Avatar from 'material-ui/Avatar'; 7 | import {grey400, darkBlack, lightBlack} from 'material-ui/styles/colors'; 8 | import IconButton from 'material-ui/IconButton'; 9 | import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert'; 10 | import IconMenu from 'material-ui/IconMenu'; 11 | import MenuItem from 'material-ui/MenuItem'; 12 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 13 | 14 | import axios from 'axios'; 15 | 16 | require('./inbox.scss'); 17 | 18 | export default class Inbox extends Component { 19 | constructor(props){ 20 | super(props) 21 | this.state = { 22 | messages: null 23 | } 24 | 25 | axios.get('/getMessages').then(response => { 26 | console.log(response.data.threads); 27 | this.setState({messages: response.data.threads}) 28 | }) 29 | } 30 | 31 | render() { 32 | 33 | const iconButtonElement = ( 34 | 39 | 40 | 41 | ); 42 | 43 | const rightIconMenu = ( 44 | 45 | Reply 46 | Forward 47 | Delete 48 | 49 | ); 50 | 51 | let threadMessages = []; 52 | 53 | if(this.state.messages !== null){ 54 | for(let i = 0; i < this.state.messages.length; i++){ 55 | var listItem =
} 57 | primaryText={this.state.messages[i].thread.other_user.user.first_name} 58 | secondaryText={ 59 |

60 | {/* */} 61 | {this.state.messages[i].thread.preview} 62 |

63 | } 64 | secondaryTextLines={2} 65 | /> 66 | 67 |
68 | threadMessages.push(listItem); 69 | } 70 | } 71 | 72 | return ( 73 | 74 | 75 | {threadMessages.length !== 0 && threadMessages.map((thread, i)=>{ 76 | return(
{thread}
) 77 | })} 78 |
79 |
80 | ) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/profile/Profile.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import FlatButton from 'material-ui/FlatButton'; 4 | import ProfileDash from "./ProfileDash"; 5 | 6 | import axios from 'axios'; 7 | 8 | const style = { 9 | padding: '0px 20px', 10 | marginLeft: 'auto', 11 | marginRight: 'auto', 12 | outline: { 13 | border: '1px solid #dce0e0' 14 | }, 15 | headerStyle: { 16 | height: '48px', 17 | padding: '15px 24px', 18 | backgroundColor: '#EDEFED', 19 | fontSize: '16px', 20 | borderBottom: '1px solid #dce0e0', 21 | }, 22 | info: { 23 | fontSize: '14px', 24 | lineHeight: '1.43', 25 | color: '#484848', 26 | padding: '25px', 27 | backgroundColor: '#fff', 28 | }, 29 | pink: { 30 | color: '#FF5A5F', 31 | cursor: 'pointer', 32 | listStyleType: 'none', 33 | } 34 | } 35 | 36 | 37 | class Profile extends Component { 38 | constructor(props){ 39 | super(props) 40 | 41 | this.state = { 42 | user: null 43 | } 44 | axios.get('/dashboard').then(response =>{ 45 | console.log(response.data.data.user.user) 46 | this.setState({user: response.data.data.user.user}) 47 | }); 48 | 49 | } 50 | 51 | render() { 52 | return ( 53 |
54 | 55 |
56 |
57 |
58 | 59 |
60 |
61 |
{this.state.user !== null && this.state.user.first_name}
62 |
View Profile
63 |
Edit Profile
64 |
65 |
66 |
67 |
68 |
69 |
{this.state.user !== null ? this.state.user.email : 'Verfications'}
70 |
Add Verifications
71 |
72 |
73 |
74 |
75 |
Quick Links
76 |
77 |
Upcoming Trips
78 |
Hosting on Airbnb
79 |
Traceling on Airbnb
80 |
Help Center
81 |
82 |
83 |
84 |
85 |
86 |
87 |
Notifications
88 |
Please confirm your email address by clicking on the link we just emailed you. If you cannot find the email, you can request a new confirmation email or change your email address.
89 |
90 |
91 | 92 | 93 |
94 |
95 | 96 |
Invite friends, earn travel credit!
97 |
98 | Invite friends, earn travel credit! 99 |
100 |
101 |
102 |
103 |
104 |
Messages
105 |
When you message hosts or send reservation requests, you’ll see their responses here.
106 |
107 |
108 |
109 |
110 |
111 | ); 112 | } 113 | } 114 | 115 | export default Profile; 116 | -------------------------------------------------------------------------------- /src/profile/ProfileDash.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | require ('./profile.component.scss'); 3 | 4 | 5 | export default React.createClass({ 6 | render(){ 7 | 8 | const style = { 9 | color: '#bbb', 10 | fontSize: '13px', 11 | padding: '9px 24px', 12 | marginLeft: 'auto', 13 | marginRight: 'auto', 14 | height: '36px', 15 | backgroundColor: '#484848', 16 | item: { 17 | padding: '10px 14px', 18 | fontWeight: '300px', 19 | }, 20 | } 21 | 22 | return( 23 |
24 |
25 | 26 | Dashboard 27 | Inbox 28 | Your Listings 29 | Your Trips 30 | Profile 31 | Account 32 | Travel Credit 33 | 34 |
35 |
36 | ) 37 | } 38 | }); 39 | -------------------------------------------------------------------------------- /src/profile/inbox.scss: -------------------------------------------------------------------------------- 1 | .threads { 2 | width: 800px; 3 | margin: 55px auto; 4 | // margin-top: 55px; 5 | background: #FFFFFF; 6 | } 7 | 8 | @media (max-width: 767px) { 9 | .threads { 10 | width: 375px; 11 | margin: 10px auto; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/profile/profile.component.scss: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: #F5F5F5; 3 | } 4 | 5 | a { 6 | text-decoration: none; 7 | color: inherit; 8 | } 9 | 10 | a:hover{ 11 | color: white; 12 | text-decoration: none; 13 | } 14 | 15 | .profile-container { 16 | padding-top: 40px; 17 | } 18 | 19 | @media (max-width: 767px) { 20 | .profilePic{ 21 | max-width: 661px; 22 | max-height: 661px; 23 | } 24 | } 25 | 26 | @media (min-width: 768px) { 27 | .profileDash { 28 | width: 730px; 29 | } 30 | .bodyWidth { 31 | width: 730px; 32 | } 33 | .profilePic{ 34 | height: 143px; 35 | width: 143px; 36 | } 37 | 38 | } 39 | @media (min-width: 1128px) { 40 | .bodyWidth { 41 | width: 1080px; 42 | } 43 | .profilePic{ 44 | height: 227px; 45 | width: 227px; 46 | } 47 | .profileDash { 48 | width: 1080px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/rooms/About.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import FlatButton from 'material-ui/FlatButton'; 4 | import MessageModal from './message-modal.js' 5 | require('./rooms.component.scss'); 6 | 7 | 8 | import axios from 'axios'; 9 | 10 | const style = { 11 | boldFont: { 12 | fontWeight: '500' 13 | } 14 | } 15 | 16 | 17 | class About extends Component { 18 | constructor(props) { 19 | super(props) 20 | 21 | this.state={ 22 | listing: { 23 | city: null, 24 | state: null, 25 | country: null, 26 | id: null, 27 | name: null, 28 | picture_url: null, 29 | price: null, 30 | thumbnail_url: null, 31 | user: { 32 | id: null, 33 | }, 34 | hosts: [{ 35 | picture_url: null, 36 | }], 37 | user_id: null, 38 | xl_picture_url: null, 39 | address: null, 40 | bathrooms: null, 41 | bedrooms: null, 42 | beds: null, 43 | cancellation_policy: null, 44 | country_code: null, 45 | has_availability: null, 46 | person_capacity: null, 47 | picture_count: null, 48 | picture_urls: [], 49 | property_type: null, 50 | reviews_count: null, 51 | room_type:null, 52 | access: null, 53 | amenities: [], 54 | cancel_policy: null, 55 | check_in_time: null, 56 | check_in_time_end: null, 57 | check_in_time_ends_at: null, 58 | check_in_time_start: null, 59 | check_out_time: null, 60 | cleaning_fee_native: null, 61 | currency_symbol_right: null, 62 | summary: null, 63 | house_rules: null, 64 | } 65 | } 66 | axios.get(`/listingInfo/${this.props.rid}`).then(hostInfo =>{ 67 | this.setState({ 68 | listing: { 69 | city: hostInfo.data.listing.city, 70 | state: hostInfo.data.listing.state, 71 | country: hostInfo.data.listing.country, 72 | id: hostInfo.data.listing.city, 73 | name: hostInfo.data.listing.name, 74 | picture_url: hostInfo.data.listing.picture_url, 75 | price: hostInfo.data.listing.price, 76 | thumbnail_url: hostInfo.data.listing.thumbnail_url, 77 | user: { 78 | id: hostInfo.data.listing.id, 79 | }, 80 | hosts: hostInfo.data.listing.hosts, 81 | user_id: hostInfo.data.listing.user_id, 82 | xl_picture_url: hostInfo.data.listing.xl_picture_url, 83 | address: hostInfo.data.listing.address, 84 | bathrooms: hostInfo.data.listing.bathrooms, 85 | bedrooms: hostInfo.data.listing.bedrooms, 86 | beds: hostInfo.data.listing.beds, 87 | cancellation_policy: hostInfo.data.listing.cancellation_policy, 88 | country_code: hostInfo.data.listing.country_code, 89 | has_availability: hostInfo.data.listing.has_availability, 90 | person_capacity: hostInfo.data.listing.person_capacity, 91 | picture_count: hostInfo.data.listing.picture_count, 92 | picture_urls: hostInfo.data.listing.picture_urls, 93 | property_type: hostInfo.data.listing.property_type, 94 | reviews_count: hostInfo.data.listing.reviews_count, 95 | room_type:hostInfo.data.listing.room_type, 96 | access: hostInfo.data.listing.access, 97 | amenities: hostInfo.data.listing.amenities, 98 | cancel_policy: hostInfo.data.listing.cancel_policy, 99 | check_in_time: hostInfo.data.listing.check_in_time, 100 | check_in_time_end: hostInfo.data.listing.check_in_time_end, 101 | check_in_time_ends_at: hostInfo.data.listing.check_in_time_ends_at, 102 | check_in_time_start: hostInfo.data.listing.check_in_time_start, 103 | check_out_time: hostInfo.data.listing.check_out_time, 104 | cleaning_fee_native: hostInfo.data.listing.cleaning_fee_native, 105 | currency_symbol_right: hostInfo.data.listing.currency_symbol_right, 106 | summary: hostInfo.data.listing.summary, 107 | house_rules: hostInfo.data.listing.house_rules, 108 | } 109 | }) 110 | }); 111 | } 112 | 113 | 114 | render() { 115 | 116 | return ( 117 |
118 |
119 |
120 |
About this listing
121 |
{this.state.listing.summary}
122 | 123 | 124 | 125 | 126 |
127 |
The Space
128 |
129 |
Accommodates: {this.state.listing.person_capacity}
130 |
Bathrooms: {this.state.listing.bathrooms}
131 |
Bedrooms: {this.state.listing.bedrooms}
132 |
Beds: {this.state.listing.beds}
133 |
134 |
135 | {(this.state.listing.check_in_time > 12) 136 | ?
Check In: Anytime after {this.state.listing.check_in_time-12}PM
137 | :
Check In: Anytime after {this.state.listing.check_in_time}AM
138 | } 139 | {(this.state.listing.check_out_time > 12) 140 | ?
Check Out:{this.state.listing.check_out_time-12}PM
141 | :
Check Out:{this.state.listing.check_out_time}AM
142 | } 143 |
Property type: {this.state.listing.property_type}
144 |
Room type: {this.state.listing.room_type}
145 |
146 |
147 |
148 |
149 | ); 150 | } 151 | } 152 | 153 | export default About; 154 | -------------------------------------------------------------------------------- /src/rooms/Header.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import FlatButton from 'material-ui/FlatButton'; 4 | import RaisedButton from 'material-ui/RaisedButton'; 5 | import Dialog from 'material-ui/Dialog'; 6 | import Slider from 'react-slick' 7 | 8 | require('./rooms.component.scss'); 9 | 10 | 11 | import axios from 'axios'; 12 | 13 | class PrevArrow extends React.Component { 14 | constructor(props) { 15 | super(props) 16 | } 17 | 18 | render() { 19 | return( 20 |
21 | 22 |
23 | ) 24 | } 25 | } 26 | 27 | class NextArrow extends React.Component { 28 | constructor(props) { 29 | super(props) 30 | } 31 | 32 | render() { 33 | 34 | return( 35 |
36 | 37 |
38 | ) 39 | } 40 | } 41 | 42 | class Header extends React.Component { 43 | constructor(props) { 44 | super(props) 45 | 46 | this.state={ 47 | open: false, 48 | listing: { 49 | price: null, 50 | picture_urls: [], 51 | } 52 | } 53 | axios.get(`/listingInfo/${this.props.rid}`).then(hostInfo =>{ 54 | console.log('hostinfo from header: ', hostInfo) 55 | this.setState({ 56 | listing: { 57 | price: hostInfo.data.listing.price, 58 | picture_urls: hostInfo.data.listing.picture_urls, 59 | } 60 | }, ()=>{ console.log('picture_urls from header: ', this.state.listing.picture_urls)}) 61 | }); 62 | } 63 | 64 | handleOpen = () => { 65 | this.setState({open: true}); 66 | }; 67 | 68 | handleClose = () => { 69 | this.setState({open: false}); 70 | }; 71 | 72 | render() { 73 | 74 | var settings = { 75 | nextArrow: , 76 | prevArrow: , 77 | arrows: true, 78 | infinite: true, 79 | speed: 200 80 | }; 81 | 82 | const actions = [ 83 | , 88 | , 94 | ]; 95 | 96 | return ( 97 | 98 |
99 | 100 | 107 | 108 | {this.state.listing.picture_urls.map((currentVal, i)=>{ 109 | return ( 110 |
111 | ) 112 | })} 113 |
114 |
115 | 116 |
117 | 118 |
${this.state.listing.price}
119 | 120 | 121 | 122 |
123 |
124 |
125 | ); 126 | } 127 | } 128 | 129 | export default Header; 130 | -------------------------------------------------------------------------------- /src/rooms/Rooms.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import Header from "./Header"; 3 | import About from "./About"; 4 | import Summary from "./Summary" 5 | import Footer from '../footer/Footer'; 6 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 7 | import FlatButton from 'material-ui/FlatButton'; 8 | import axios from 'axios'; 9 | require('./rooms.component.scss'); 10 | 11 | 12 | class Rooms extends Component { 13 | constructor(props) { 14 | super(props) 15 | } 16 | 17 | 18 | render() { 19 | 20 | console.log("props", this.props.params.rid); 21 | return ( 22 |
23 |
24 | 25 | 26 |
27 |
28 | ); 29 | } 30 | } 31 | 32 | export default Rooms; 33 | -------------------------------------------------------------------------------- /src/rooms/Summary.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 3 | import Home from 'material-ui/svg-icons/action/home'; 4 | import People from 'material-ui/svg-icons/social/people-outline'; 5 | import Contacts from 'material-ui/svg-icons/communication/contacts'; 6 | import Bed from 'material-ui/svg-icons/notification/airline-seat-individual-suite'; 7 | 8 | require('./rooms.component.scss'); 9 | 10 | 11 | 12 | import axios from 'axios'; 13 | 14 | class Summary extends React.Component { 15 | constructor(props) { 16 | super(props) 17 | 18 | this.state={ 19 | listing: { 20 | city: null, 21 | state: null, 22 | country: null, 23 | name: null, 24 | picture_url: null, 25 | user: { 26 | id: null, 27 | }, 28 | hosts: [{ 29 | picture_url: null, 30 | }], 31 | bedrooms: null, 32 | beds: null, 33 | person_capacity: null, 34 | reviews_count: null, 35 | room_type:null, 36 | } 37 | } 38 | axios.get(`/listingInfo/${this.props.rid}`).then(hostInfo =>{ 39 | 40 | console.log("hostInfo: " , hostInfo) 41 | 42 | this.setState({ 43 | listing: { 44 | city: hostInfo.data.listing.city, 45 | state: hostInfo.data.listing.state, 46 | country: hostInfo.data.listing.country, 47 | name: hostInfo.data.listing.name, 48 | picture_url: hostInfo.data.listing.picture_url, 49 | user: { 50 | id: hostInfo.data.listing.id, 51 | }, 52 | hosts: hostInfo.data.listing.hosts, 53 | bedrooms: hostInfo.data.listing.bedrooms, 54 | beds: hostInfo.data.listing.beds, 55 | person_capacity: hostInfo.data.listing.person_capacity, 56 | reviews_count: hostInfo.data.listing.reviews_count, 57 | room_type:hostInfo.data.listing.room_type, 58 | } 59 | }) 60 | }); 61 | } 62 | 63 | 64 | render() { 65 | return ( 66 |
67 |
68 |
69 | 70 |
{this.state.listing.hosts[0].first_name}
71 |
72 | 73 |
74 |
{this.state.listing !== undefined && this.state.listing.name}
75 |
{this.state.listing !== undefined && this.state.listing.city} {this.state.listing.state} {this.state.listing.country}
76 |
77 | 78 | 79 | 80 | 81 |
82 |
83 | 84 |
{this.state.listing !== undefined && this.state.listing.room_type}
85 |
86 |
87 | 88 | {(this.state.listing !== undefined && this.state.listing.person_capacity === 1) 89 | ?
{this.state.listing !== undefined && this.state.listing.person_capacity} guest
90 | :
{this.state.listing !== undefined && this.state.listing.person_capacity} guests
91 | } 92 |
93 |
94 | 95 | {(this.state.listing !== undefined && this.state.listing.bedrooms === 1) 96 | ?
{this.state.listing !== undefined && this.state.listing.bedrooms} bedroom
97 | :
{this.state.listing !== undefined && this.state.listing.bedrooms} bedrooms
98 | } 99 |
100 |
101 | 102 | {(this.state.listing !== undefined && this.state.listing.beds === 1) 103 | ?
{this.state.listing !== undefined && this.state.listing.beds} bed
104 | :
{this.state.listing !== undefined && this.state.listing.beds} beds
105 | } 106 |
107 |
108 |
109 |
110 |
111 |
112 | ); 113 | } 114 | } 115 | 116 | export default Summary; 117 | -------------------------------------------------------------------------------- /src/rooms/message-modal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Dialog from 'material-ui/Dialog'; 3 | import FlatButton from 'material-ui/FlatButton'; 4 | import RaisedButton from 'material-ui/RaisedButton'; 5 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 6 | import Divider from 'material-ui/Divider'; 7 | import Paper from 'material-ui/Paper'; 8 | import TextField from 'material-ui/TextField'; 9 | import axios from 'axios'; 10 | 11 | const style = { 12 | marginLeft: 20, 13 | width: '330px' 14 | }; 15 | 16 | const customContentStyle = { 17 | width: '400px', 18 | maxWidth: 'none', 19 | }; 20 | 21 | const pink = { 22 | color: '#FF5E63', 23 | borderColor: '#FF5E63' 24 | } 25 | 26 | const grey = { 27 | color: '#EDEFED', 28 | } 29 | 30 | const modalHeader={ 31 | backgroundColor: '#EDEFED', 32 | fontSize: '16px', 33 | padding: "9px 15px 8px" 34 | } 35 | 36 | export default class blop extends React.Component { 37 | 38 | constructor(props){ 39 | super(props) 40 | this.state = { 41 | open: false, 42 | message: null, 43 | }; 44 | } 45 | 46 | handleOpen = () => { 47 | this.setState({open: true}); 48 | }; 49 | 50 | handleClose = () => { 51 | this.setState({open: false}); 52 | }; 53 | 54 | submitMessage = () => { 55 | console.log(this.state.message); 56 | axios.post('/sendMessage', {message:this.state.message, id:this.props.rid} ).then(response => { console.log(response)}) 57 | this.setState({open: false}); 58 | } 59 | 60 | onMessage = (e) => { 61 | this.setState({message: e.target.value}, () => { 62 | return console.log(this.state.message); 63 | }) 64 | } 65 | 66 | render() { 67 | 68 | const actions = [ 69 | , 75 | , 82 | ]; 83 | 84 | const form =
85 | 86 | 94 | 95 |
96 | 97 | return ( 98 | 99 |
100 |
Contact Host
101 | 110 | {form} 111 | 112 |
113 |
114 | ); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/rooms/rooms.component.scss: -------------------------------------------------------------------------------- 1 | .cnt-sm-left-md{ 2 | text-align: center; 3 | } 4 | .about-body{ 5 | padding-left: 10vw; 6 | padding-right: 10vw; 7 | } 8 | .header-picture{ 9 | height: 400px; 10 | width: auto; 11 | } 12 | .pics-slider { 13 | overflow: hidden; 14 | } 15 | 16 | .prev-arrow-header { 17 | position: absolute; 18 | top: 200px; 19 | z-index: 10; 20 | left: 15px; 21 | text-shadow: 0px 0px 3px #555; 22 | } 23 | 24 | .next-arrow-header { 25 | position: absolute; 26 | z-index: 10; 27 | right: 15px; 28 | top: 200px; 29 | text-shadow: 0 0 3px #555; 30 | } 31 | 32 | @media (min-width: 768px) { 33 | .cnt-sm-left-md{ 34 | text-align: left; 35 | } 36 | .about-body{ 37 | padding: 15px; 38 | } 39 | .header-picture{ 40 | height: 460px; 41 | width: auto; 42 | } 43 | 44 | } 45 | @media (min-width: 1128px) { 46 | .header-picture{ 47 | height: 550px; 48 | width: auto; 49 | } 50 | } 51 | .room-slider { 52 | text-align: center; 53 | } 54 | 55 | .img-slide { 56 | display: inline-block !important; 57 | text-align: center; 58 | } -------------------------------------------------------------------------------- /src/search-results/SearchResults.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import axios from 'axios' 4 | import Navbar from '../navbar/Navbar.js' 5 | import moment from 'moment' 6 | import Rheostat from 'rheostat' 7 | import _ from 'lodash' 8 | import Slider from 'react-slick' 9 | import { Link } from 'react-router' 10 | 11 | import DateRangePickerGmapPage from '../date-range-picker/DateRangePickerGmapPage.jsx'; 12 | 13 | require('./searchResults.scss'); 14 | require('./date-picker-results.scss'); 15 | 16 | var sliderMin = 0; 17 | 18 | class ProgressBar extends React.Component { 19 | constructor(props) { 20 | super(props) 21 | } 22 | 23 | render() { 24 | return( 25 |
26 | ) 27 | } 28 | } 29 | 30 | class PrevArrow extends React.Component { 31 | constructor(props) { 32 | super(props) 33 | } 34 | 35 | render() { 36 | return( 37 |
38 | 39 |
40 | ) 41 | } 42 | } 43 | 44 | class NextArrow extends React.Component { 45 | constructor(props) { 46 | super(props) 47 | } 48 | 49 | render() { 50 | 51 | return( 52 |
53 | 54 |
55 | ) 56 | } 57 | } 58 | 59 | export default class SearchResults extends React.Component { 60 | 61 | constructor(props) { 62 | super(props) 63 | 64 | this.state = { 65 | iCenter: { 66 | lng: -90.1056957, 67 | lat: 29.9717272 68 | }, 69 | checker: false, 70 | icon: { 71 | path: 'M 0,0 20,0 20,16 14,16 10,24 6,16 0,16 z', 72 | fillColor: '#FF5A5F', 73 | fillOpacity: 1, 74 | scale: 1.5, 75 | strokeColor: 'RGBA(100,100,100,0.5)', 76 | strokeWeight: 1, 77 | }, 78 | entireHome: false, 79 | privateRoom: false, 80 | sharedRoom: false, 81 | location: null, 82 | data: null, 83 | startDate: null, 84 | endDate: null, 85 | numGuests: 1, 86 | values: [0,100], 87 | sliderMin: 0, 88 | sliderMax: 100, 89 | roomTypeSelected: null, 90 | picture_urls: [], 91 | propertyNames: [], 92 | star_rating: [], 93 | price_array: [], 94 | room_type_array: [], 95 | id_array: [] 96 | } 97 | 98 | axios.get('/getData').then(response => { 99 | 100 | const x = response.data; 101 | 102 | this.setState({ 103 | iCenter: { 104 | lat: x.center_lat, 105 | lng: x.center_lng 106 | }, 107 | location: x.canonical_location_en 108 | }) 109 | 110 | this.setState({ 111 | data: x, 112 | location: x.location, 113 | startDate: x.startDate, 114 | endDate: x.endDate, 115 | numGuests: x.numGuests, 116 | sliderMax: x.max_price_total, 117 | sliderMin: x.min_price_total, 118 | values: [x.min_price_total, x.max_price_total] 119 | }, ()=>{ 120 | this.renderMap(x); 121 | }); 122 | 123 | 124 | }) 125 | } 126 | 127 | static propTypes() { 128 | initialCenter: React.PropTypes.objectOf(React.PropTypes.number).isRequired 129 | } 130 | 131 | render = () => { 132 | 133 | var settings = { 134 | nextArrow: , 135 | prevArrow: , 136 | arrows: true, 137 | infinite: true, 138 | slidesToShow: 1, 139 | slidesToScroll: 1, 140 | speed: 0.0001 141 | }; 142 | 143 | let arrOfSliders = []; 144 | 145 | if(this.state.picture_urls.length != 0){ 146 | for(let i = 0; i < this.state.picture_urls.length; i++){ 147 | var slider =
148 |
149 |
150 |
151 |
152 |
153 |
154 |
${this.state.price_array[i]}
155 |
156 |

{this.state.propertyNames[i]}

157 |

{this.state.room_type_array[i]} {this.state.star_rating[i]}

158 |
159 |
160 | arrOfSliders.push(slider); 161 | } 162 | } 163 | 164 | return( 165 |
166 |
167 |
168 |
169 | Dates 170 |
171 |
172 |
173 | Room Types 174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | Price Range 182 | 183 |
    184 | {this.state.values.map((value, i) => ( 185 |
  • 186 | ${this.props.formatValue ? this.props.formatValue(value) : value} 187 |
  • 188 | ))} 189 |
190 |
191 |
192 | {arrOfSliders.map((slider, i)=>{ 193 | return( 194 |
{slider}
195 | ) 196 | })} 197 |
198 |
199 |
200 |
201 |
202 | ) 203 | } 204 | 205 | updateValue = (sliderState) => { 206 | 207 | const renderMap = _.debounce(this.renderMap, 300); 208 | 209 | this.setState({ 210 | values: sliderState.values, 211 | }, renderMap(this.state.roomTypeSelected, this.state.values)); 212 | } 213 | 214 | handleRoomTypes = (e) => { 215 | 216 | if (e.target.value === 'false') { 217 | this.setState({[e.target.id]: true}, ()=>{ 218 | let arr = [this.state.entireHome, this.state.privateRoom, this.state.sharedRoom]; 219 | return this.renderMap(this.convertToNames(arr)); 220 | }); 221 | } else if (e.target.value === 'true') { 222 | 223 | this.setState({[e.target.id]: false}, ()=>{ 224 | let arr = [this.state.entireHome, this.state.privateRoom, this.state.sharedRoom]; 225 | return this.renderMap(this.convertToNames(arr)); 226 | } 227 | ); 228 | } 229 | } 230 | 231 | convertToNames = (arr) => { 232 | var names = ['Entire home/apt', 'Private room', 'Shared room']; 233 | 234 | for(let i = 0; i < arr.length; i++){ 235 | 236 | if(arr[i] === false){ 237 | names.splice(i,1); 238 | arr.splice(i,1); 239 | i--; 240 | } 241 | } 242 | 243 | this.setState({roomTypeSelected: names}); 244 | return names 245 | } 246 | 247 | createMap = () => { 248 | let mapOptions = { 249 | center: this.mapCenter() 250 | } 251 | return new google.maps.Map(this.refs.mapCanvas, mapOptions) 252 | } 253 | 254 | mapCenter = () => { 255 | 256 | return new google.maps.LatLng( 257 | this.state.iCenter.lat, 258 | this.state.iCenter.lng 259 | ) 260 | } 261 | 262 | createMarker = (lat, lng, price, name, pic, id, room_type, infowindow) => { 263 | 264 | var position = new google.maps.LatLng( 265 | lat, lng 266 | ); 267 | 268 | let contentString = `
269 |
270 |
$${price}
271 |
272 |

${name}

273 |

${room_type}

274 |
` 275 | 276 | var marker = new Marker({ 277 | position: position, 278 | map: this.map, 279 | infowindow: infowindow, 280 | icon: { 281 | path: SQUARE_PIN, 282 | fillOpacity: 0, 283 | strokeWeight: 0, 284 | }, 285 | map_icon_label: '$' + price + '' 286 | }) 287 | 288 | google.maps.event.addListener(marker, 'click', () => { 289 | infowindow.setContent(contentString); 290 | infowindow.open(this.map, marker); 291 | }); 292 | 293 | google.maps.event.addListener(this.map, "click", () => { 294 | infowindow.close(); 295 | }); 296 | 297 | return marker 298 | } 299 | 300 | renderMap = (arr, priceRange = [null,null]) => { 301 | 302 | axios.post('/search',{ 303 | searchVal: this.state.location, 304 | startDate: this.state.startDate, 305 | endDate: this.state.endDate, 306 | numGuests: this.state.numGuests, 307 | room_types: arr, 308 | price_min: this.state.sliderMin, 309 | price_max: this.state.sliderMax, 310 | }).then(response => { 311 | 312 | const x = response.data; 313 | 314 | console.log('XXX',x); 315 | 316 | let listingsArray = response.data.results_json.search_results; 317 | this.map = this.createMap() 318 | this.latlngbounds = new google.maps.LatLngBounds(); 319 | 320 | let pics_array = []; 321 | let propertyNames = []; 322 | let star_rating = []; 323 | let price_array = []; 324 | let room_type_array = []; 325 | let id_array = []; 326 | 327 | var infowindow = new google.maps.InfoWindow() 328 | 329 | for (let i = 0; i < listingsArray.length; i++) { 330 | 331 | const lat = listingsArray[i].listing.lat 332 | const lng = listingsArray[i].listing.lng 333 | 334 | this.marker = this.createMarker(lat, lng, listingsArray[i].pricing_quote.rate.amount, listingsArray[i].listing.name, listingsArray[i].listing.picture_url, listingsArray[i].listing.id, listingsArray[i].listing.room_type, infowindow) 335 | 336 | var myLatLng = new google.maps.LatLng(lat, lng); 337 | this.latlngbounds.extend(myLatLng); 338 | 339 | pics_array.push(listingsArray[i].listing.picture_urls); 340 | propertyNames.push(listingsArray[i].listing.name); 341 | star_rating.push(listingsArray[i].listing.star_rating); 342 | price_array.push(listingsArray[i].pricing_quote.rate.amount); 343 | room_type_array.push(listingsArray[i].listing.room_type); 344 | id_array.push(listingsArray[i].listing.id); 345 | 346 | this.setState({picture_urls: pics_array, 347 | propertyNames: propertyNames, 348 | star_rating: star_rating, 349 | price_array: price_array, 350 | room_type_array: room_type_array, 351 | id_array: id_array 352 | }) 353 | } 354 | 355 | if(x.max_price_total === null && x.min_price_total === null){ 356 | const min = Math.min(...price_array); 357 | const max = Math.max(...price_array); 358 | this.setState({ 359 | sliderMin: min, 360 | sliderMax: max, 361 | values: [min, max] 362 | }) 363 | } 364 | 365 | this.map.fitBounds(this.latlngbounds); 366 | 367 | this.setState({ 368 | iCenter: { 369 | lat: x.center_lat, 370 | lng: x.center_lng 371 | } 372 | }) 373 | }) 374 | } 375 | 376 | } 377 | -------------------------------------------------------------------------------- /src/search-results/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "googleSimpleKey": "AIzaSyA5IuG1nWY56ZA8bJcp0cPElZiX6jIqFKg" 3 | } 4 | -------------------------------------------------------------------------------- /src/search-results/searchResults.scss: -------------------------------------------------------------------------------- 1 | .tempVals { 2 | display: flex; 3 | flex-direction: row; 4 | justify-content: space-between; 5 | list-style-type: none; 6 | margin-bottom: 3px; 7 | } 8 | 9 | .val { 10 | margin: 0 30px; 11 | 12 | } 13 | 14 | .container-search { 15 | width: 100%; 16 | // height: 60vh; 17 | position: absolute; 18 | } 19 | 20 | .GMap-canvas { 21 | display: block; 22 | width: 41%; 23 | height: 90vh; 24 | float: right; 25 | } 26 | 27 | .cards-container { 28 | float: left; 29 | background: white; 30 | } 31 | 32 | .UpdatedText { 33 | color: red; 34 | } 35 | 36 | .price { 37 | color: white; 38 | } 39 | 40 | .date-panel { 41 | border-top: 1px solid RGBA(100,100,100,0.2); 42 | padding-top: 15px; 43 | padding-bottom: 15px; 44 | background-color: #fff; 45 | z-index: 10; 46 | position: relative; 47 | // margin: 15px 0 0; 48 | padding: 25px; 49 | box-sizing: border-box; 50 | font-family: 'Roboto',"Helvetica Neue",Helvetica,Arial,sans-serif; 51 | font-size: 14px; 52 | line-height: 1.43; 53 | color: #484848; 54 | -webkit-font-smoothing: antialiased; 55 | width: 100%; 56 | height: 70px; 57 | display: flex; 58 | flex-direction: row; 59 | position: relative; 60 | } 61 | 62 | .dates-panel-label { 63 | margin-left: 8px; 64 | } 65 | 66 | .room-panel { 67 | border-top: 1px solid RGBA(100,100,100,0.2); 68 | padding-top: 15px; 69 | padding-bottom: 15px; 70 | background-color: #fff; 71 | z-index: 10; 72 | position: relative; 73 | // margin: 15px 0 0; 74 | box-sizing: border-box; 75 | font-family: 'Roboto',"Helvetica Neue",Helvetica,Arial,sans-serif; 76 | font-size: 14px; 77 | line-height: 1.43; 78 | color: #484848; 79 | -webkit-font-smoothing: antialiased; 80 | width: 100%; 81 | height: 70px; 82 | display: flex; 83 | flex-direction: row; 84 | } 85 | 86 | .dates { 87 | font-family: 'Roboto',"Helvetica Neue",Helvetica,Arial,sans-serif; 88 | font-size: 15px; 89 | line-height: 1.43; 90 | color: #484848; 91 | -webkit-font-smoothing: antialiased; 92 | margin: 0; 93 | padding-top: 4px; 94 | } 95 | 96 | //Section Searchbox 97 | .date-picker{ 98 | width: 70%; 99 | } 100 | 101 | .date-picker-container { 102 | position:absolute; 103 | left: 50%; 104 | top: 50%; 105 | transform: (translate(-50%, -50%)); 106 | width: 100%; 107 | } 108 | 109 | .SearchBar { 110 | box-sizing: border-box; 111 | -webkit-writing-mode: horizontal-tb; 112 | font: 11px BlinkMacSystemFont; 113 | letter-spacing: normal; 114 | word-spacing: normal; 115 | text-transform: none; 116 | text-indent: 0; 117 | text-shadow: none; 118 | text-rendering: auto; 119 | -webkit-rtl-ordering: logical; 120 | -webkit-user-select: text; 121 | cursor: auto; 122 | line-height: normal; 123 | font-family: "Roboto","Helvetica Neue","Helvetica","Arial", sans-serif; 124 | border-radius: 2px; 125 | background-color: #fff; 126 | color: #484848; 127 | border: 1px solid #c4c4c4; 128 | display: block; 129 | padding: 8px 10px; 130 | // width: 100%; 131 | font-size: 16px; 132 | padding-top: 10px; 133 | padding-bottom: 10px; 134 | border-right: 0; 135 | border-top-right-radius: 0; 136 | border-bottom-right-radius: 0; 137 | float: left; 138 | height: 50px; 139 | width: 200px; 140 | } 141 | 142 | .DatePicker { 143 | float: left; 144 | } 145 | 146 | .SearchBarContainer { 147 | width: 100%; 148 | max-width: 100%; 149 | } 150 | 151 | .selectGuest { 152 | box-sizing: border-box; 153 | -webkit-writing-mode: horizontal-tb; 154 | text-align: start; 155 | text-rendering: auto; 156 | letter-spacing: normal; 157 | word-spacing: normal; 158 | text-indent: 0; 159 | text-shadow: none; 160 | align-items: center; 161 | overflow: visible !important; 162 | margin: 0; 163 | -webkit-font-smoothing: antialiased; 164 | font-family: "Roboto","Helvetica Neue","Helvetica","Arial", sans-serif; 165 | border: 1px solid #c4c4c4; 166 | border-radius: 2px; 167 | background-color: #fff; 168 | color: #484848; 169 | display: block; 170 | padding: 8px 10px; 171 | -webkit-appearance: none; 172 | padding-right: 2em; 173 | padding-top: 10px; 174 | padding-bottom: 10px; 175 | border-bottom-right-radius: 0; 176 | border-top-right-radius: 0; 177 | width: 120px; 178 | font-size: 17px; 179 | white-space: pre; 180 | -webkit-rtl-ordering: logical; 181 | background: URL('../../assets/images/down-arrow.png'); 182 | background-position: right; 183 | background-repeat: no-repeat; 184 | background-color: white; 185 | height: 50px; 186 | } 187 | 188 | .SearchBtn { 189 | box-sizing: border-box; 190 | font-family: "Roboto","Helvetica Neue","Helvetica","Arial", sans-serif; 191 | text-indent: 0; 192 | text-shadow: none; 193 | letter-spacing: normal; 194 | word-spacing: normal; 195 | margin: 0; 196 | -webkit-appearance: button; 197 | -webkit-font-smoothing: antialiased; 198 | cursor: pointer; 199 | border-radius: 2px; 200 | border: 1px solid; 201 | text-align: center; 202 | vertical-align: middle; 203 | font-weight: bold; 204 | margin-bottom: 0; 205 | background: white; 206 | font-size: 16px; 207 | display: block; 208 | white-space: normal; 209 | border-bottom-left-radius: 0; 210 | border-top-left-radius: 0; 211 | border-color: #ff5a5f; 212 | border-bottom-color: #e00007; 213 | background-color: #ff5a5f; 214 | color: #fff; 215 | width: 150px; 216 | } 217 | 218 | .room-type-container { 219 | background: #EDEFED; 220 | width: 160px; 221 | height: 40px; 222 | margin: 0 0 0 15px; 223 | text-align: center; 224 | display: flex; 225 | flex-direction: row; 226 | justify-content: space-between; 227 | 228 | } 229 | 230 | .room-types-header { 231 | display: inline-block; 232 | margin-left: 20px; 233 | padding:12px; 234 | } 235 | 236 | .room-type-checkbox-section { 237 | padding: 10px 5px 0 0; 238 | } 239 | 240 | .checkbox { 241 | margin-left: 5px; 242 | margin-right: 5px; 243 | } 244 | 245 | input[type='checkbox'] { 246 | -webkit-appearance:none; 247 | height: 1.25em; 248 | width: 1.25em; 249 | margin-bottom: -0.25em; 250 | vertical-align: top; 251 | border-radius: 2px; 252 | background-color: #fff; 253 | color: #484848; 254 | border: 1px solid grey; 255 | } 256 | 257 | input[type='checkbox']:checked:before { 258 | content: "\2713"; 259 | font-size: 1em; 260 | margin-left: 2px; 261 | margin-bottom: 2px; 262 | text-align: center; 263 | width: 1.25em; 264 | color: #ff5a5f; 265 | } 266 | 267 | .checkboxes { 268 | display: flex; 269 | flex-direction: row; 270 | // width: 60%; 271 | position:absolute; 272 | left: 50%; 273 | top: 50%; 274 | transform: (translate(-50%, -50%)); 275 | } 276 | 277 | .room-type-icon { 278 | margin: 7px 0 0 7px; 279 | padding: 0 0 0 5px; 280 | height: auto; 281 | width: auto; 282 | max-width: 27px; 283 | max-height: 27px; 284 | } 285 | 286 | .rheostat-container { 287 | margin-top: 5px; 288 | width: 100%; 289 | } 290 | 291 | .rheostat { 292 | margin: auto; 293 | width: 85%; 294 | position: relative; 295 | height: 24px; 296 | overflow: visible; 297 | margin-bottom: 12px; 298 | display: block; 299 | -webkit-font-smoothing: antialiased; 300 | font-family: 'Roboto',"Helvetica Neue",Helvetica,Arial,sans-serif; 301 | font-size: 14px; 302 | line-height: 1.43; 303 | color: #484848; 304 | background-color: #fcfcfc; 305 | position: relative; 306 | } 307 | 308 | .rheostat-background { 309 | background: #BBBBBB; 310 | height: 2px; 311 | position: relative; 312 | top: 14px; 313 | width: 100%; 314 | display: block; 315 | font-family: 'Roboto',"Helvetica Neue",Helvetica,Arial,sans-serif; 316 | font-size: 14px; 317 | line-height: 1.43; 318 | color: #484848; 319 | -webkit-font-smoothing: antialiased; 320 | box-sizing: border-box; 321 | } 322 | 323 | .rheostat-progress { 324 | background-color: #FF5A5F; 325 | position: absolute; 326 | height: 3px; 327 | width: 100%; 328 | margin-top: 12px; 329 | margin-left: 4px; 330 | } 331 | 332 | .rheostat-handle { 333 | left: 0; 334 | position: absolute; 335 | border: 1px solid #aaa; 336 | background: #fff; 337 | border-radius: 100%; 338 | box-shadow: 0 2px 4px rgba(0,0,0,0.1); 339 | cursor: pointer; 340 | height: 24px; 341 | margin-left: -12px; 342 | outline: none; 343 | z-index: 2; 344 | width: 24px; 345 | font-size: 0; 346 | line-height: inherit; 347 | font-family:inherit; 348 | -webkit-font-smoothing: antialiased; 349 | -webkit-appearance: button; 350 | text-transform: none; 351 | margin: 0; 352 | align-items: flex-start; 353 | text-align: center; 354 | text-rendering: auto; 355 | letter-spacing: normal; 356 | word-spacing: normal; 357 | text-indent: 0; 358 | text-shadow: none; 359 | font: 11px BlinkMacSystemFont; 360 | box-sizing: border-box; 361 | } 362 | 363 | .rheostat-handle:after, 364 | .rheostat-handle:before { 365 | content: ''; 366 | display: block; 367 | position: absolute; 368 | background-color: #dadfe8; 369 | } 370 | 371 | .arrayOfSliders { 372 | display: flex; 373 | flex-direction: row; 374 | flex-wrap: wrap; 375 | justify-content: center; 376 | // border: 1px dotted teal; 377 | width: 100%; 378 | height: 65vh; 379 | background: #F5F5F5; 380 | padding-top: 30px; 381 | overflow: scroll; 382 | } 383 | 384 | .slider-container { 385 | margin: 0 20px; 386 | width: 400px; 387 | // border: 1px dotted red; 388 | box-sizing: border-box; 389 | height: 290px; 390 | position: relative; 391 | } 392 | 393 | .img-container { 394 | width: 400px; 395 | height: 210px; 396 | overflow: hidden; 397 | // border: 1px dotted blue; 398 | } 399 | 400 | .price-inside-img { 401 | position: absolute; 402 | color: white; 403 | font-size: 20px; 404 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 405 | position: absolute; 406 | top: 160px; 407 | background: rgba(45,45,45,0.9); 408 | padding: 7px 15px 7px 15px; 409 | } 410 | 411 | .slider-img { 412 | width: 100%; 413 | } 414 | 415 | .panel-card-section { 416 | padding: 12px 15px 12px 15px; 417 | } 418 | 419 | .img-title { 420 | font-size: 16px; 421 | line-height: 1.1; 422 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 423 | box-sizing: border-box; 424 | color: #525252; 425 | margin: 0px; 426 | } 427 | 428 | .room-type-card-section { 429 | color: #9d9d9d; 430 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 431 | font-size: 15px; 432 | margin-top: 4px; 433 | } 434 | 435 | .prev-arrow { 436 | position: absolute; 437 | top: 70px; 438 | z-index: 10; 439 | left: 15px; 440 | text-shadow: 1px 1px #dddddd; 441 | } 442 | 443 | .next-arrow { 444 | position: absolute; 445 | z-index: 10; 446 | right: 15px; 447 | top: 70px; 448 | text-shadow: 1px 1px #dddddd; 449 | } 450 | 451 | .img-container-gmap { 452 | width: 200px; 453 | height: 105px; 454 | overflow: hidden; 455 | // border: 1px dotted blue; 456 | } 457 | 458 | .price-inside-img-gmap { 459 | position: absolute; 460 | color: white; 461 | font-size: 15px; 462 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 463 | position: absolute; 464 | top: 65px; 465 | background: rgba(45,45,45,0.9); 466 | padding: 7px 15px 7px 15px; 467 | } 468 | 469 | .slider-img-gmap { 470 | width: 100%; 471 | margin: 0 auto 472 | } 473 | 474 | .gm-style-iw + div { 475 | display: none; 476 | } 477 | 478 | .gm-style-iw { 479 | // border: 1px dotted pink; 480 | padding-left:10px; 481 | margin: 0; 482 | } 483 | 484 | .panel-card-section-gmap { 485 | padding: 6px 7px 0px 7px; 486 | // border: 1px dotted teal; 487 | width:200px; 488 | } 489 | 490 | .img-title-gmap { 491 | font-size: 13px; 492 | line-height: 1; 493 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 494 | box-sizing: border-box; 495 | color: #525252; 496 | margin: 0; 497 | -webkit-margin-before: 0em; 498 | -webkit-margin-after: 0em; 499 | -webkit-margin-start: 0px; 500 | -webkit-margin-end: 0px; 501 | } 502 | 503 | .room-type-card-section-gmap { 504 | color: #9d9d9d; 505 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 506 | font-size: 12px; 507 | margin-top: 7px; 508 | margin-bottom: 0px; 509 | -webkit-margin-before: 0em; 510 | -webkit-margin-after: 0em; 511 | -webkit-margin-start: 0px; 512 | -webkit-margin-end: 0px; 513 | } 514 | 515 | @media (min-width: 768px) { 516 | .cards-container, { 517 | width: 59%; 518 | } 519 | } 520 | -------------------------------------------------------------------------------- /src/shared.js: -------------------------------------------------------------------------------- 1 | var common = require("./common"); 2 | module.exports = function(msg) { 3 | console.log(msg); 4 | }; -------------------------------------------------------------------------------- /src/stepper/Stepper.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Step, 4 | Stepper, 5 | StepLabel, 6 | StepContent, 7 | } from 'material-ui/Stepper'; 8 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 9 | import RaisedButton from 'material-ui/RaisedButton'; 10 | import FlatButton from 'material-ui/FlatButton'; 11 | 12 | /** 13 | * Vertical steppers are designed for narrow screen sizes. They are ideal for mobile. 14 | * 15 | * To use the vertical stepper with the contained content as seen in spec examples, 16 | * you must use the `` component inside the ``. 17 | * 18 | * (The vertical stepper can also be used without `` to display a basic stepper.) 19 | */ 20 | class VerticalLinearStepper extends React.Component { 21 | 22 | state = { 23 | finished: false, 24 | stepIndex: 0, 25 | }; 26 | 27 | handleNext = () => { 28 | const {stepIndex} = this.state; 29 | this.setState({ 30 | stepIndex: stepIndex + 1, 31 | finished: stepIndex >= 2, 32 | }); 33 | }; 34 | 35 | handlePrev = () => { 36 | const {stepIndex} = this.state; 37 | if (stepIndex > 0) { 38 | this.setState({stepIndex: stepIndex - 1}); 39 | } 40 | }; 41 | 42 | renderStepActions(step) { 43 | const {stepIndex} = this.state; 44 | 45 | return ( 46 |
47 | 55 | {step > 0 && ( 56 | 63 | )} 64 |
65 | ); 66 | } 67 | 68 | render() { 69 | const {finished, stepIndex} = this.state; 70 | 71 | return ( 72 |
73 | 74 | 75 | 76 | Select campaign settings 77 | 78 |

79 | For each ad campaign that you create, you can control how much 80 | you're willing to spend on clicks and conversions, which networks 81 | and geographical locations you want your ads to show on, and more. 82 |

83 | {this.renderStepActions(0)} 84 |
85 |
86 | 87 | Create an ad group 88 | 89 |

An ad group contains one or more ads which target a shared set of keywords.

90 | {this.renderStepActions(1)} 91 |
92 |
93 | 94 | Create an ad 95 | 96 |

97 | Try out different ad text to see what brings in the most customers, 98 | and learn how to enhance your ads using features like ad extensions. 99 | If you run into any problems with your ads, find out how to tell if 100 | they're running and how to resolve approval issues. 101 |

102 | {this.renderStepActions(2)} 103 |
104 |
105 |
106 |
107 | 108 | {finished && ( 109 |

110 | { 113 | event.preventDefault(); 114 | this.setState({stepIndex: 0, finished: false}); 115 | }} 116 | > 117 | Click here 118 | to reset the example. 119 |

120 | )} 121 |
122 | ); 123 | } 124 | } 125 | 126 | export default VerticalLinearStepper; -------------------------------------------------------------------------------- /src/user/User.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import axios from 'axios' 3 | 4 | export default class User extends Component { 5 | constructor(props){ 6 | super(props) 7 | 8 | // axios.defaults.withCredentials = true 9 | axios.get('/viewUser/'+props.params.id).then(response => { console.log('response: ', response) }); 10 | } 11 | 12 | render() { 13 | return ( 14 |
{this.props.params.first_name && this.props.params.first_name}
15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | var CommonsChunkPlugin = require("./node_modules/webpack/lib/optimize/CommonsChunkPlugin"); 4 | 5 | var alias = { 6 | "react/lib/CSSPropertyOperations": "react-dom/lib/CSSPropertyOperations" 7 | }; 8 | 9 | module.exports = { 10 | entry: { 11 | main: "./src/App.js", 12 | becomeAHost: ["./src/become-a-host/BecomeAHost.js"], 13 | profile: ["./src/profile/Profile.js"], 14 | rooms: ["./src/rooms/Rooms.js"], 15 | searchResults: ["./src/search-results/SearchResults.js"], 16 | }, 17 | output: { 18 | path: path.join(__dirname, "public/bundle/"), 19 | filename: "[name].js" 20 | }, 21 | resolve: { 22 | alias: alias 23 | }, 24 | plugins: [ 25 | new CommonsChunkPlugin({ 26 | filename: "commons.js", 27 | name: "commons" 28 | }) 29 | ], 30 | devtools: "sourcemap", 31 | module: { 32 | loaders: [ 33 | { 34 | test: /\.jsx?$/, 35 | exclude: /node_modules/, 36 | loader: "babel" 37 | }, 38 | 39 | { 40 | test: /\.scss$/, 41 | loaders: ["style", "css", "sass"], 42 | exclude: /node_modules/ 43 | }, 44 | { test: /\.svg$/, 45 | loader: 'babel!react-svg', 46 | include: path.join(__dirname, 'src') }, 47 | ] 48 | } 49 | } 50 | --------------------------------------------------------------------------------