diff --git a/.gitignore b/.gitignore index 13de78d..95dedc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules/ -app/static/img/user_pics/ +#app/static/img/user_pics/ diff --git a/app/controllers/cart.js b/app/controllers/cart.js new file mode 100644 index 0000000..78b53ea --- /dev/null +++ b/app/controllers/cart.js @@ -0,0 +1,45 @@ +'use strict'; + +var Gift = require('../models/gift'), + config = require('../../config'); + +exports.add = function(req, res){ + Gift.findById(req.body.giftId, function(err, gift){ + req.session.cart = req.session.cart || []; + req.session.cart.push(gift); + req.session.save(function(){ + res.redirect('/cart'); + }); + }); +}; + +exports.index = function(req, res){ + var gifts = {}, + subtotal = 0, + tax = 0, + total = 0; + + (req.session.cart || []).forEach(function(g){ + subtotal += g.price; + var id = g._id.toString(); + gifts[id] = gifts[id] || {g:g, c:0}; + gifts[id].c++; + }); + + tax = subtotal * 0.075; + total = subtotal + tax; + + req.session.totalCents = Math.round(total * 100); + req.session.save(function(){ + + res.render('users/checkout', {key:config.stripe.publishKey, ids:Object.keys(gifts), gifts:gifts, subtotal:subtotal, tax:tax, total:total}); + }); +}; + +exports.destroy = function(req, res){ + req.session.cart = []; + req.session.save(function(){ + res.redirect('/cart'); + }); +}; + diff --git a/app/controllers/gifts.js b/app/controllers/gifts.js new file mode 100644 index 0000000..a9c1196 --- /dev/null +++ b/app/controllers/gifts.js @@ -0,0 +1,9 @@ +'use strict'; + +var Gift = require('../models/gift'); + +exports.index = function(req, res){ + Gift.findAll(function(err, gifts){ + res.render('users/gifts', {gifts:gifts}); + }); +}; diff --git a/app/controllers/users.js b/app/controllers/users.js index 192ac30..b28aab7 100644 --- a/app/controllers/users.js +++ b/app/controllers/users.js @@ -1,6 +1,7 @@ 'use strict'; var User = require('../models/user'), + Message = require('../models/message'), mp = require('multiparty'); exports.new = function(req, res){ @@ -32,19 +33,19 @@ exports.profile = function(req, res){ res.render('users/profile'); }; -exports.addPhoto = function(req, res){ +exports.addPhotos = function(req, res){ var form = new mp.Form(); form.parse(req, function(err, fields, files){ // console.log('fields', fields); // console.log('files', files); - User.addPhotos(req.user, fields, files, function(){ + User.addPhotos(req.user, files, function(){ res.redirect('/profile'); }); }); }; exports.setProfilePhoto = function(req, res){ - req.user.setProfilePhoto(req.body, function(){ + req.user.setProfilePhoto(req.body.index, function(){ res.redirect('/profile'); }); }; @@ -67,15 +68,44 @@ exports.contact = function(req, res){ }); }; -// For creating modals - please DELETE me! -exports.editDetails = function(req, res){ - res.render('users/details'); +exports.verify = function(req, res){ + if(!req.user.alias){ + res.render('users/init-info'); + }else{ + res.redirect('/profile'); + } }; -exports.editAbout = function(req, res){ - res.render('users/about'); + +exports.initUpdate = function(req, res){ + req.user.initUpdate(req.body, function(err){ + if(err){ + req.flash('error', err); + res.redirect('/verify'); + }else{ + res.redirect('/profile'); + } + }); }; -exports.editContact = function(req, res){ - res.render('users/contact'); + +exports.send = function(req, res){ + User.findById(req.params.userId, function(err, receiver){ + res.locals.user.send(receiver, req.body, function(){ + res.redirect('/users/' + receiver.email); + }); + }); +}; + +exports.messages = function(req, res){ + res.locals.user.messages(function(err, msgs){ + res.render('users/messages', {msgs:msgs}); + }); }; -// END DELETE NOTE +exports.message = function(req, res){ + Message.read(req.params.msgId, function(err, msg){ + res.render('users/message', {msg:msg}); + }); +}; +exports.alias = function(req, res){ + res.render('users/alias'); +}; diff --git a/app/lib/mongodb.js b/app/lib/mongodb.js index 7f00914..10e4fee 100644 --- a/app/lib/mongodb.js +++ b/app/lib/mongodb.js @@ -5,10 +5,12 @@ var MongoClient = require('mongodb').MongoClient; module.exports = function(name, cb){ var url = 'mongodb://localhost/' + name; MongoClient.connect(url, function(err, db){ - global.mongodb = db; - - console.log('Express: Database', name); - if(cb){cb();} + db.collection('users').ensureIndex({'coordinates':'2dsphere'}, function(err, indexName){ + // console.log('********ensureIndexErr', err); + global.mongodb = db; + console.log('Express: Database', name); + if(cb){cb();} + }); }); }; diff --git a/app/lib/passport/deserialize.js b/app/lib/passport/deserialize.js index 2019441..8a33685 100644 --- a/app/lib/passport/deserialize.js +++ b/app/lib/passport/deserialize.js @@ -4,6 +4,6 @@ var User = require('../../models/user'); module.exports = function(obj, cb){ // console.log('******Deserialize', obj); - User.findById(obj.userId, cb); + User.findByIdSession(obj.userId, cb); }; diff --git a/app/models/gift.js b/app/models/gift.js new file mode 100644 index 0000000..aac059c --- /dev/null +++ b/app/models/gift.js @@ -0,0 +1,24 @@ +'use strict'; + +var Mongo = require('mongodb'); + +function Gift(){ +} + +Object.defineProperty(Gift, 'collection', { + get: function(){return global.mongodb.collection('gifts');} +}); + +Gift.findById = function(id, cb){ + var _id = Mongo.ObjectID(id); + Gift.collection.findOne({_id:_id}, cb); +}; + +Gift.findAll = function(cb){ + Gift.collection.find().toArray(cb); +}; + + + +module.exports = Gift; + diff --git a/app/models/message.js b/app/models/message.js new file mode 100644 index 0000000..3fd3ff6 --- /dev/null +++ b/app/models/message.js @@ -0,0 +1,47 @@ +'use strict'; + +var async = require('async'), + Mongo = require('mongodb'); + +function Message(senderId, receiverId, message){ + this.senderId = senderId; + this.receiverId = receiverId; + this.message = message; + this.date = new Date(); + this.isRead = false; +} + +Object.defineProperty(Message, 'collection', { + get: function(){return global.mongodb.collection('messages');} +}); + +Message.read = function(id, cb){ + var _id = Mongo.ObjectID(id); + Message.collection.findAndModify({_id:_id}, [], {$set:{isRead:true}}, function(err, msg){ + iterator(msg, cb); + }); +}; + +Message.send = function(senderId, receiverId, message, cb){ + var m = new Message(senderId, receiverId, message); + Message.collection.save(m, cb); +}; + +Message.unread = function(receiverId, cb){ + Message.collection.find({receiverId:receiverId, isRead:false}).count(cb); +}; + +Message.messages = function(receiverId, cb){ + Message.collection.find({receiverId:receiverId}).sort({date:-1}).toArray(function(err, msgs){ + async.map(msgs, iterator, cb); + }); +}; + +module.exports = Message; + +function iterator(msg, cb){ + require('./user').findById(msg.senderId, function(err, sender){ + msg.sender = sender; + cb(null, msg); + }); +} diff --git a/app/models/user.js b/app/models/user.js index 5ec9b56..96af2a7 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -3,16 +3,27 @@ var bcrypt = require('bcrypt'), Mongo = require('mongodb'), _ = require('underscore-contrib'), + Message = require('./message'), fs = require('fs'), path = require('path'); function User(){ + this.coordinates = []; } Object.defineProperty(User, 'collection', { get: function(){return global.mongodb.collection('users');} }); +User.findByIdSession = function(id, cb){ + var _id = Mongo.ObjectID(id); + User.collection.findOne({_id:_id}, {fields:{alias:1, email:1, coordinates:1, type:1, location:1, zip:1}}, function(err, obj){ + var user = Object.create(User.prototype); + user = _.extend(user, obj); + cb(err, user); + }); +}; + User.findById = function(id, cb){ var _id = Mongo.ObjectID(id); User.collection.findOne({_id:_id}, function(err, obj){ @@ -26,7 +37,10 @@ User.register = function(o, cb){ User.collection.findOne({email:o.email}, function(err, user){ if(user){return cb();} o.password = bcrypt.hashSync(o.password, 10); - User.collection.save(o, cb); + o.type = 'local'; + user = new User(); + user = _.extend(user, o); + User.collection.save(user, cb); }); }; @@ -45,7 +59,8 @@ User.googleAuth = function(accessToken, refreshToken, profile, cb){ // console.log(accessToken, refreshToken, profile, cb); User.collection.findOne({googleId:profile.id}, function(err, user){ if(user){return cb(err, user);} - user = {googleId:profile.id, displayName:profile.displayName, type:'google'}; + user = new User(); + user = _.extend(user, {googleId:profile.id, type:'google'}); User.collection.save(user, cb); }); }; @@ -54,26 +69,13 @@ User.facebookAuth = function(accessToken, refreshToken, profile, cb){ // console.log(profile); User.collection.findOne({facebookId:profile.id}, function(err, user){ if(user){return cb(err, user);} - user = {facebookId:profile.id, displayName:profile.displayName, type:'facebook'}; + user = new User(); + user = _.extend(user, {facebookId:profile.id, type:'facebook'}); User.collection.save(user, cb); }); }; -User.updateProfile = function(user, fields, files, cb){ - // console.log('***Post Body:', fields); - Object.keys(fields).forEach(function(key){ - fields[key][0] = fields[key][0].trim(); - if(fields[key][0]){ - switch(key){ - case 'visible': - user.isPublic = (fields[key] === 'public'); - break; - default: - user[key] = fields[key][0]; - } - } - }); - // console.log('*** Updated User:', user); +User.addPhotos = function(user, files, cb){ user.moveFiles(files); User.collection.save(user, cb); }; @@ -108,5 +110,64 @@ User.prototype.moveFiles = function(files){ this.photos = this.photos.concat(photos); }; +User.prototype.initUpdate = function(data, cb){ + // console.log('************DATA', data); + var self = this; + User.collection.findOne({alias:data.alias}, function(err1, obj1){ + if(obj1){return cb('Please choose a different alias, that one is already in use');} + data.coordinates.forEach(function(c, i){ + data.coordinates[i] = parseFloat(c); + }); + User.collection.update({_id:self._id}, {$set:{alias:data.alias, email:data.email, location:data.location, coordinates:data.coordinates, phone:data.phone, zip:data.zip}}, cb); + }); +}; + +User.prototype.updateAbout = function(data, cb){ + Object.keys(data).forEach(function(key){ + data[key] = data[key].trim(); + }); + User.collection.update({_id:this._id}, {$set:{about:data}}, cb); +}; + +User.prototype.updateDetails = function(data, cb){ + User.collection.update({_id:this._id}, {$set:{details:data}}, cb); +}; + +User.prototype.setProfilePhoto = function(index, cb){ + User.collection.findOne({_id:this._id}, {fields:{photos:1}}, function(err, data){ + var i = data.photos.map(function(x){return x.isPrimary;}).indexOf(true); + if(i !== -1){data.photos[i].isPrimary = false;} + data.photos[index].isPrimary = true; + User.collection.update({_id:data._id}, {$set:{photos:data.photos}}, cb); + }); +}; +// NEED TO TOUCH BASE BEFORE FINISHING +/* +User.prototype.updateContact = function(data, cb){ +}; +*/ + +User.prototype.unread = function(cb){ + Message.unread(this._id, cb); +}; + +User.prototype.save = function(o, cb){ + var properties = Object.keys(o), + self = this; + properties.forEach(function(property){ + self[property] = o[property]; + }); + delete this.unread; + User.collection.save(self, cb); +}; + +User.prototype.messages = function(cb){ + Message.messages(this._id, cb); +}; + +User.prototype.send = function(receiver, obj, cb){ + Message.send(this._id, receiver._id, obj.message, cb); +}; + module.exports = User; diff --git a/app/routes/routes.js b/app/routes/routes.js index a3273c1..2f0b3a7 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -12,6 +12,7 @@ var morgan = require('morgan'), passportConfig = require('../lib/passport/config'), debug = require('../lib/debug'), home = require('../controllers/home'), + gifts = require('../controllers/gifts'), users = require('../controllers/users'); module.exports = function(app, express){ @@ -20,7 +21,7 @@ module.exports = function(app, express){ app.use(express.static(__dirname + '/../static')); app.use(bodyParser.urlencoded({extended:true})); app.use(methodOverride()); - app.use(session({store:new RedisStore(), secret:'HashLikeABoss', resave:true, saveUninitialized:true, cookie:{maxAge:null}})); + app.use(session({store:new RedisStore(), secret:'WickedUnbreakableHash', resave:true, saveUninitialized:true, cookie:{maxAge:null}})); app.use(flash()); passportConfig(passport, app); @@ -31,26 +32,28 @@ module.exports = function(app, express){ app.get('/register', users.new); app.post('/register', users.create); app.get('/login', users.login); - app.post('/login', passport.authenticate('local', {successRedirect:'/profile', failureRedirect:'/login', failureFlash:'Login failed'})); + app.post('/login', passport.authenticate('local', {successRedirect:'/verify', failureRedirect:'/login', failureFlash:'Login failed'})); app.get('/auth/google', passport.authenticate('google', {scope: ['https://www.googleapis.com/auth/plus.login', 'https://www.googleapis.com/auth/plus.profile.emails.read']})); - app.get('/auth/google/callback', passport.authenticate('google', {successRedirect:'/profile', failureRedirect:'/login', failureFlash:'Google Login failed'})); + app.get('/auth/google/callback', passport.authenticate('google', {successRedirect:'/verify', failureRedirect:'/login', failureFlash:'Google Login failed'})); app.get('/auth/facebook', passport.authenticate('facebook')); - app.get('/auth/facebook/callback', passport.authenticate('facebook', {successRedirect:'/profile', failureRedirect:'/login', failureFlash:'Facebook Login failed'})); + app.get('/auth/facebook/callback', passport.authenticate('facebook', {successRedirect:'/verify', failureRedirect:'/login', failureFlash:'Facebook Login failed'})); app.use(security.bounce); app.delete('/logout', users.logout); + app.get('/verify', users.verify); app.get('/profile', users.profile); - app.post('/profile/photos', users.addPhoto); + app.put('/profile/init', users.initUpdate); + app.post('/profile/photos', users.addPhotos); app.put('/profile/photos/primary', users.setProfilePhoto); app.put('/profile/about', users.about); app.put('/profile/details', users.details); app.put('/profile/contact', users.contact); - - // For creating modal - please DELETE me! - app.get('/profile/details', users.editDetails); - app.get('/profile/contact', users.editContact); - app.get('/profile/about', users.editAbout); - // END DELETE NOTE + app.put('/profile/about', users.details); + app.post('/message/:userId', users.send); + app.get('/messages', users.messages); + app.get('/messages/:msgId', users.message); + app.get('/users/alias', users.alias); + app.get('/gifts', gifts.index); console.log('Express: Routes Loaded'); }; diff --git a/app/static/css/style.css b/app/static/css/style.css index e69de29..d693ee5 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -0,0 +1 @@ +@import url(http://fonts.googleapis.com/css?family=Codystar);@import url(http://fonts.googleapis.com/css?family=Oswald);@import url(http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300);.navbar{height:55px}.navbar-default .navbar-nav>li>a{font-size:15px}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0;margin-top:6px}.navbar-brand{font-family:'Codystar',cursive;font-size:50px;font-weight:bold}.navbar-default .navbar-brand{color:#FFE87F;font-weight:bold;position:absolute}#messagesTable{height:190px;overflow:scroll}#winksTable{height:190px;overflow:scroll}#proposalsTable{height:190px;overflow:scroll}#close{float:left}#cart{display:inline-block}#giftImg img{max-height:100px;max-width:100px}#index{background-color:rgba(0,0,0,0.2);border-radius:4%;font-family:'Open Sans Condensed',sans-serif;box-shadow:6px 23px 31px -2px rgba(0,0,0,0.75)}thead{background-color:white;color:black}td,th{text-align:center}div.c-wrapper{width:80%;margin:auto}.carousel-inner>.item>img,.carousel-inner>.item>a>img{width:100%;margin:auto}.gifts{background-image:url('/img/cart.jpg');background-size:cover;width:100%;height:800px;background-repeat:no-repeat;margin:0} \ No newline at end of file diff --git a/app/static/css/style.less b/app/static/css/style.less index 1d298e8..3b91e7a 100644 --- a/app/static/css/style.less +++ b/app/static/css/style.less @@ -1,5 +1,92 @@ +@import url(http://fonts.googleapis.com/css?family=Codystar); +@import url(http://fonts.googleapis.com/css?family=Oswald); +@import url(http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300); body { } +.navbar{ + height: 55px; +} + +.navbar-default .navbar-nav>li>a { +font-size: 15px; +} + +.container>.navbar-header, .container-fluid>.navbar-header, .container>.navbar-collapse, .container-fluid>.navbar-collapse { + margin-right: 0; + margin-left: 0; + margin-top: 6px; +} + +.navbar-brand{ + font-family: 'Codystar', cursive; + font-size: 50px; + font-weight: bold; +} +.navbar-default .navbar-brand { + color: #FFE87F; + font-weight: bold; + position: absolute; +} + +#messagesTable{ + height: 190px; + overflow: scroll; +} +#winksTable{ + height: 190px; + overflow: scroll; +} +#proposalsTable{ + height: 190px; + overflow: scroll; +} + +#close { + float: left; +} + +#cart { + display: inline-block; +} + +#giftImg img { + max-height: 100px; + max-width: 100px; +} + +#index { + background-color: rgba(0,0,0,.2); + border-radius: 4%; + font-family: 'Open Sans Condensed', sans-serif; + box-shadow: 6px 23px 31px -2px rgba(0,0,0,0.75); + } + thead { + background-color: white; + color: black; + } + td, th { + text-align: center; +} + +div.c-wrapper{ + width: 80%; /* for example */ + margin: auto; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img{ + width: 100%; /* use this, or not */ + margin: auto; +} + +.gifts { + background-image: url('/img/cart.jpg'); + background-size: cover; + width: 100%; + height: 800px; + background-repeat: no-repeat; + margin: 0; +} diff --git a/app/static/img/cart.jpg b/app/static/img/cart.jpg new file mode 100644 index 0000000..122f31e Binary files /dev/null and b/app/static/img/cart.jpg differ diff --git a/app/static/img/user_pics/.gitignore b/app/static/img/user_pics/.gitignore new file mode 100644 index 0000000..76bedae --- /dev/null +++ b/app/static/img/user_pics/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore + diff --git a/app/static/js/user/init-info.js b/app/static/js/user/init-info.js new file mode 100644 index 0000000..c43537b --- /dev/null +++ b/app/static/js/user/init-info.js @@ -0,0 +1,28 @@ +/* jshint unused:false, camelcase:false */ +/* global google */ + +(function(){ + 'use strict'; + + $(document).ready(function(){ + $('button[type=submit]').click(geocodeAndSubmit); + }); + + function geocodeAndSubmit(e){ + var geocoder = new google.maps.Geocoder(), + zip = $('input[name=zip]').val(); + geocoder.geocode({address:zip}, function(results, status){ + console.log('results', results); + var name = results[0].formatted_address, + lat = results[0].geometry.location.lat(), + lng = results[0].geometry.location.lng(); + $('input[name=location]').val(name); + $('input[data-name=lat]').val(lat); + $('input[data-name=lng]').val(lng); + $('form').submit(); + }); + e.preventDefault(); + } + +})(); + diff --git a/app/views/home/index.jade b/app/views/home/index.jade index f460cba..fd15681 100644 --- a/app/views/home/index.jade +++ b/app/views/home/index.jade @@ -1,30 +1,7 @@ extends ../shared/template block content - h2 Home - .panel.panel-default - .panel-body - h4 Visual Flair - ul - li: a(href='http://fontawesome.io/icons/', target='_blank') Font Awesome Icons - li: a(href='http://fontawesome.io/examples/', target='_blank') Font Awesome Examples with Bootstrap - li - a.btn.btn-info(href='#'): i.fa.fa-camera.fa-5x   Photo - li - a.btn.btn-default.btn-sm(href='#'): i.fa.fa-cog   Settings - li: a(href='http://subtlepatterns.com/', target='_blank') Subtle Backgrounds - li: a(href='http://www.paletton.com/', target='_blank') Color Palette Generator - h4 Bootstrap Themes and Templates - ul - li: a(href='http://bootswatch.com/', target='_blank') http://bootswatch.com/ - li: a(href='http://bootstrapzero.com/', target='_blank') http://bootstrapzero.com/ - li: a(href='http://startbootstrap.com/', target='_blank') http://startbootstrap.com/ - li: a(href='http://www.prepbootstrap.com/', target='_blank') http://www.prepbootstrap.com/ - li: a(href='http://www.blacktie.co/', target='_blank') http://www.blacktie.co/ - li: a(href='https://bootstrapmaster.com/', target='_blank') https://bootstrapmaster.com/ - li: a(href='http://bootstrapstyler.com/', target='_blank') http://bootstrapstyler.com/ - h4 Favicon Generators - ul - li: a(href='http://www.favicon.cc/', target='_blank') http://www.favicon.cc/ + + h1 block scripts script(src='/js/user/home.js') diff --git a/app/views/shared/flash.jade b/app/views/shared/flash.jade new file mode 100644 index 0000000..e351cba --- /dev/null +++ b/app/views/shared/flash.jade @@ -0,0 +1,21 @@ +each error in flash.error || [] + .alert.alert-danger.alert-dismissible(role='alert') + button.close(type="button", data-dismiss="alert") + span(aria-hidden="true") × + span.sr-only Close + strong Warning!   + span= error +each notice in flash.notice || [] + .alert.alert-info.alert-dismissible(role='alert') + button.close(type="button", data-dismiss="alert") + span(aria-hidden="true") × + span.sr-only Close + strong Notice!   + span= notice +each success in flash.success || [] + .alert.alert-success.alert-dismissible(role='alert') + button.close(type="button", data-dismiss="alert") + span(aria-hidden="true") × + span.sr-only Close + strong Success!   + span= success diff --git a/app/views/shared/nav.jade b/app/views/shared/nav.jade index bacd53e..b1e5dd9 100644 --- a/app/views/shared/nav.jade +++ b/app/views/shared/nav.jade @@ -12,11 +12,14 @@ ul.nav.navbar-nav.navbar-right if user li: a(href='/Profile') Profile + li: a(href='/messages') + span.fa.fa-envelope   Inbox   + span.badge= 0 li form.navbar-form(method='post', action='/logout') .form-group input(type='hidden', name='_method', value='delete') - button.btn.btn-danger= user.email || user.username || user.displayName + button.btn.btn-danger Log Out else li: a(href='/register') Register li: a(href='/login') Login diff --git a/app/views/shared/template.jade b/app/views/shared/template.jade index 71908ba..99b4bdc 100644 --- a/app/views/shared/template.jade +++ b/app/views/shared/template.jade @@ -10,6 +10,7 @@ html(lang='en') link(rel='stylesheet', href='/css/style.css') body include nav + include flash .container-fluid .row .col-xs-12 diff --git a/app/views/users/about.jade b/app/views/users/about.jade index f0dc93d..4dd9eb0 100644 --- a/app/views/users/about.jade +++ b/app/views/users/about.jade @@ -1,22 +1,20 @@ -extends ../shared/template -block content - h2 Edit Profile - .row - .col-xs-6 - // TRIGGER - button.btn.btn-primary.btn-md(data-toggle='modal', data-target='#editAbout') - | Edit About - // MODAL - #editAbout.modal.fade(tabindex='-1', role='dialog', aria-labelledby='editAboutLabel', aria-hidden='true') - .modal-dialog.modal-lg - .modal-content - .modal-header - button.close(type='button', data-dismiss='modal') - span(aria-hidden='true') × - span.sr-only Close - h4#editAboutLabel.modal-title Edit your about me - .modal-body - form.form-horizontal#about_form(role='form', method='post', action='/profile') - input(type='hidden', name='_method', value='put') - .form-group - +// TRIGGER +button.btn.btn-warning-btn-mini(data-toggle='modal', data-target='#editAbout'): i.fa.fa-edit +// MODAL +#editAbout.modal.fade(tabindex='-1', role='dialog', aria-labelledby='editAboutLabel', aria-hidden='true') + .modal-dialog + .modal-content + .modal-header + button.close(type='button', data-dismiss='modal') + span(aria-hidden='true') × + span.sr-only Close + h4#editAboutLabel.modal-title Edit your about me + .modal-body + form#about_form(role='form', method='post', action='/profile/about') + input(type='hidden', name='_method', value='put') + .form-group + label.control-label(for='aboutMe') About Me + textarea#aboutMe.form-control(rows='4', name='aboutMe') + .modal-footer + button.btn.btn-default(type='button', data-dismiss='modal') Close + button.btn.btn-success(type='submit') Save changes diff --git a/app/views/users/alias.jade b/app/views/users/alias.jade new file mode 100644 index 0000000..c844d5a --- /dev/null +++ b/app/views/users/alias.jade @@ -0,0 +1,58 @@ +extends ../shared/template +block content + .panel.panel-default + .panel-body + .row + .col-xs-4 + h2 user.alias + .col-xs-4 + ul.list-inline + li + h5 user.age + li + h5 user.gender + li + h5 user.location + .col-xs-2 + a.thumbnail#alias(href='#') + img(src='/img/node.png') + .col-xs-2.col-xs-offset-1 + span.glyphicon.glyphicon-heart + .col-xs-4 + + button.btn.btn-default.btn-(data-toggle='modal', data-target='#newMessage') Message + include newMessage + a.btn.btn-default.btn(href='/gifts') Gift + //button.btn.btn-default.btn-(data-toggle='modal', data-target='#gift') Gift + //include checkout + button.btn.btn-default.btn-(data-toggle='modal', data-target='wink') Wink + span.glyphicon.glyphicon-eye-open + .row + .col-xs-12 + .panel.panel-default + .panel-heading + h3.panel-title About # {client.alias} + .panel-body + h6 This is the About Me Section of the Profile Page + .row + .col-xs-12 + .c-wrapper + #carousel.carousel.slide(data-ride='carousel') + ol.carousel-indicators + li.active(data-target='#carouse', data-slide-to='0') + li.active(data-target='#carousel', data-slide-to='1') + li.active(data-target='#carousel', data-slide-to='2') + .carousel-inner + .item.active + img(src='/img/node.png') + .item + img(src='/img/node.png') + a.left.carousel-control(href='#carousel', role='button', data-slide='prev') + span.glyphicon.glyphicon-chevron-left + a.right.carousel-control(href='#carousel', role='button', data-slide='prev') + span.glyphicon.glyphicon-chevron-right + + + + +block scripts diff --git a/app/views/users/checkout.jade b/app/views/users/checkout.jade new file mode 100644 index 0000000..7f94499 --- /dev/null +++ b/app/views/users/checkout.jade @@ -0,0 +1,52 @@ +#gift.modal.fade(tabindex='-1', role='dialog', aria-labelledby='giftlLabel', aria-hidden='true') + .modal-dialog + .modal-content + .modal-header + button.close(type='button', data-dismiss='modal', aria-hidden='true') × + h4.modal-title Send a Gift + .modal-body + table#gifts.table.table-bordered + thead + tr + th Product + th Image + th Price + th Quantity + th SubTotal + tbody + loop each id in ids + tr + td = gifts[id].g.name + td(style='background-image:url("# {gifts[id].g.photo}")') + td $# {gifts[id].g.price.toFixed(2)} + td = gifts[id].c + td = '$' + (gifts[id].g.price * gifts[id].c).toFixed(2) + tr + td + td + td + td Subtotal + td = '$' + subtotal.toFixed(2) + tr + td + td + td + td Tax + td = '$' + tax.toFixed(2) + tfoot + tr + td + td + td + td Total + td = '$' + total.toFixed(2) + .modal-footer + button#close.btn.btn-default(type='button', data-dismiss='modal') Close + form#cart(method='post', action='/cart') + input(type='hidden', name='_method', value='delete') + button.stripe-button(type='submit') Clear Cart + form#cart(action='/charge', method='post') + script.stripe-button(src='https://checkout.stripe.com/checkout.js', data-key=key, data-image='/img/marketplace.png', data-name='AmazonSP', data-amount=Math.round((total * 100))) + + + diff --git a/app/views/users/contact.jade b/app/views/users/contact.jade index d5e07a1..c2e8d1c 100644 --- a/app/views/users/contact.jade +++ b/app/views/users/contact.jade @@ -1,56 +1,47 @@ -extends ../shared/template -block content - h2 Edit Profile - .row - .col-xs-6 - // TRIGGER - button.btn.btn-primary.btn-md(data-toggle='modal', data-target='#editContact') - | Edit Contact Information - // MODAL - #editContact.modal.fade(tabindex='-1', role='dialog', aria-labelledby='editContactLabel', aria-hidden='true') - .modal-dialog - .modal-content - .modal-header - button.close(type='button', data-dismiss='modal') - span(aria-hidden='true') × - span.sr-only Close - h4#editContactLabel.modal-title Edit your contact information - .modal-body - form.form-horizontal#contact_form(role='form', method='post', action='/profile') - input(type='hidden', name='_method', value='put') - .form-group - label.col-xs-2.control-label(for='alias') Alias - .col-xs-8 - input(type='hidden', name='_method', value='put') - input.form-control#alias(type='text', name='alias', value=user.alias, autofocus=true) - span.help-block - | Other members can only see your alias. - .form-group - label.col-xs-2.control-label(for='name') Name - .col-xs-8 - input.form-control#name(type='text', name='name', value=user.name) - .form-group - label.col-xs-2.control-label(for='email') Email - .col-xs-8 - input.form-control#email(type='email', name='email', value=user.email) - .form-group - label.col-xs-2.control-label(for='Phone') Phone - .col-xs-8 - input.form-control#phone(type='tel', name='phone', value=user.phone) - .form-group - label.col-xs-2.control-label(for='address') Address - br - .col-xs-8 - label.input_separator(for='address[street]') Street - input.form-control#street(type='text', name='address[street]', placeholder= '7018 Hollywood Blvd.') - label.input_separator(for='address[city]') City - input.form-control#city(type='text', name='address.[city]', placeholder='Hollywood') - label.input_separator(for='address[state]') State - input.form-control#state(type='text', name='address.[state]', placeholder='CA') - label.input_separator(for='address[zip]') ZIP - input.form-control#zip(type='text', name='address.[zip]', placeholder='90028') - // MODAL FOOTER - .modal-footer - button.btn.btn-default(type='button', data-dismiss='modal') Close - button.btn.btn-success(type='button') Save changes - +// TRIGGER +button.btn.btn-primary-btn-sm(data-toggle='modal', data-target='#editContact'): i.fa.fa-edit +// MODAL +#editContact.modal.fade(tabindex='-1', role='dialog', aria-labelledby='editContactLabel', aria-hidden='true') + .modal-dialog + .modal-content + .modal-header + button.close(type='button', data-dismiss='modal') + span(aria-hidden='true') × + span.sr-only Close + h4#editContactLabel.modal-title Edit your contact information + .modal-body + form.form-horizontal#contact_form(role='form', method='post', action='/profile/contact') + input(type='hidden', name='_method', value='put') + .form-group + label.col-xs-2.control-label(for='alias') Alias + .col-xs-8 + input.form-control#alias(type='text', name='alias', value=user.alias, autofocus=true) + span.help-block + | Other members can only see your alias. + .form-group + label.col-xs-2.control-label(for='name') Name + .col-xs-8 + input.form-control#name(type='text', name='name', value=user.name) + .form-group + label.col-xs-2.control-label(for='email') Email + .col-xs-8 + input.form-control#email(type='email', name='email', value=user.email) + .form-group + label.col-xs-2.control-label(for='Phone') Phone + .col-xs-8 + input.form-control#phone(type='tel', name='phone', value=user.phone) + .form-group + label.col-xs-2.control-label(for='address') Address + br + .col-xs-8 + label.input_separator(for='address[street]') Street + input.form-control#street(type='text', name='address[street]', placeholder= '7018 Hollywood Blvd.') + label.input_separator(for='address[city]') City + input.form-control#city(type='text', name='address.[city]', placeholder='Hollywood') + label.input_separator(for='address[state]') State + input.form-control#state(type='text', name='address.[state]', placeholder='CA') + label.input_separator(for='address[zip]') ZIP + input.form-control#zip(type='text', name='address.[zip]', placeholder='90028') + .modal-footer + button.btn.btn-default(type='button', data-dismiss='modal') Close + button.btn.btn-success(type='submit') Save changes diff --git a/app/views/users/details.jade b/app/views/users/details.jade index bd0fb48..ba5de86 100644 --- a/app/views/users/details.jade +++ b/app/views/users/details.jade @@ -1,338 +1,325 @@ -extends ../shared/template -block content - h2 Edit Profile - .row - .col-xs-6 - // TRIGGER - button.btn.btn-primary.btn-md(data-toggle='modal', data-target='#editDetails') - | Edit Details - // MODAL - #editDetails.modal.fade(tabindex='-1', role='dialog', aria-labelledby='editDetailsLabel', aria-hidden='true') - .modal-dialog.modal-lg - .modal-content - .modal-header - button.close(type='button', data-dismiss='modal') - span(aria-hidden='true') × - span.sr-only Close - h4#editDetailsLabel.modal-title Edit your details - .modal-body - form.form-horizontal#details_form(role='form', method='post', action='/profile') - input(type='hidden', name='_method', value='put') - .form-group - label.col-lg-2.control-label(for='orientation') Orientation - .col-lg-10 - select#orientation.form-control - option(selected='') - - option Asexual - option Bisexual - option Exploring - option Gay - option Heterosexual / Straight - br - .form-group - label.col-lg-2.control-label(for='ethnicities') Ethnicity - .col-lg-3 - label.checkbox(for='ethnicity1') - input#ethnicity1(type='checkbox', name='ethnicities') - span.icon - | Asian - label.checkbox(for='ethnicity2') - input#ethnicity2(type='checkbox', name='ethnicities') - span.icon - | Middle Eastern - label.checkbox(for='ethnicity3') - input#ethnicity3(type='checkbox', name='ethnicities') - span.icon - | Black - .col-lg-3 - label.checkbox(for='ethnicity4') - input#ethnicity4(type='checkbox', name='ethnicities') - span.icon - | Native American - label.checkbox(for='ethnicity5') - input#ethnicity5(type='checkbox', name='ethnicities') - span.icon - | Indian - label.checkbox(for='ethnicity6') - input#ethnicity6(type='checkbox', name='ethnicities') - span.icon - | Pacific Islander - .col-lg-3 - label.checkbox(for='ethnicity7') - input#ethnicity7(type='checkbox', name='ethnicities') - span.icon - | Hispanic / Latin - label.checkbox(for='ethnicity8') - input#ethnicity8(type='checkbox', name='ethnicities') - span.icon - | White - label.checkbox(for='ethnicity9') - input#ethnicity9(type='checkbox', name='ethnicities') - span.icon - | Other - .form-group - label.col-lg-2.control-label(for='feet') Height - #feetContainer.inputcontainer.select - select#feet(name='feet') - option — - option 7 - option 6 - option 5 - option 4 - option 3 - label.input_separator(for='feet') feet - #inchesContainer.inputcontainer.select - select#inches(name='inches') - option 0 - option 1 - option 2 - option 3 - option 4 - option 5 - option 6 - option 7 - option 8 - option 9 - option 10 - option 11 - label.input_separator(for='inches') inches - .form-group - label(for='bodyType') Body Type - #bodyTypeContainer.inputcontainer.select - select#bodyType(name='bodyType') - option(selected='') — - option Rather not say - option Thin - option Overweight - option Skinny - option Average - option Fit - option Athletic - option Jacked - option A little extra - option Curvy - option Full figured - option Used up - .form-group - label(for='diet') Diet - #dietContainer.inputcontainer.select - select#diet(name='diet') - option — - option anything - option halal - option kosher - option vegan - option vegetarian - option other - #dietSeriousContainer.inputcontainer.select - select#dietSerious(name='dietSerious') - option — - option Mostly - option Strictly - .form-group - label(for='smoking') Smokes - #smokingContainer.inputcontainer.select - select#smoking(name='smoking') - option(selected='') — - option Yes - option Sometimes - option When drinking - option Trying to quit - option No - .form-group - label(for='drinking') Drinks - #drinkingContainer.inputcontainer.select - select#drinking(name='drinking') - option(selected='') — - option Very often - option Often - option Socially - option Rarely - option Desperately - option Not at all - .form-group - label(for='drug') Drug of Choice - #drugContainer.inputcontainer.select - select#drug(name='drug') - option(selected='') — - optgroup(label='Narcotics') - option Heroin - option Hydromorphone - option Methadone - option Morphine - option Opium - option Oxycodone - optgroup(label='Stimulants') - option Amphetamines - option Cocaine - option Khat - option Methamphetamine - optgroup(label='Depressants') - option Barbiturates - option Benzodiazepines - option GHB - option Rohypnol - optgroup(label='Hallucinogens') - option Ecstasy / MDMA - option K2 / Spice - option Ketamine - option LSD - option Peyote & Mescaline - option Psilocybin - option Marijuana / Cannabis - option Steroids - option Inhalants - optgroup(label='Other') - option Bath Salts / Designer Cathinones - option DXM - option Salvia Divinorum - .form-group - label(for='religion') Religion - #religionContainer.inputcontainer.select - select#religion(name='religion') - option(selected='') — - option Agnosticism - option Atheism - option Christianity - option Judaism - option Catholicism - option Islam - option Hinduism - option Buddhism - option Other - #religionSeriousContainer.inputcontainer.select - select#religionSerious(name='religionSerious') - option(selected='') — - option and very serious about it - option and somewhat serious about it - option but not too serious about it - option and laughing about it - .form-group - label(for='sign') Sign - #signContainer.inputcontainer.select - select#sign(name='sign') - option(selected='') — - option Aquarius - option Pisces - option Aries - option Taurus - option Gemini - option Cancer - option Leo - option Virgo - option Libra - option Scorpio - option Sagittarius - option Capricorn - #signSeriousContainer.inputcontainer.select - select#signSerious(name='signSerious') - option — - option but it doesn’t matter - option and it matters a lot - option and it’s fun to think about - .form-group - label(for='educationStatus') Education - #educationStatusContainer.inputcontainer.select - select#educationStatus(name='educationStatus') - option(selected='') — - option Graduated from - option Working on - option Dropped out of - #educationLevelContainer.inputcontainer.select - select#educationLevel(name='educationLevel') - option(selected='') — - option high school - option acting school - option two-year college - option university - option masters program - option law school - option med school - option Ph.D program - option space camp - option school of hard knocks - .form-group - label(for='job') Ulmer Status - #ulmerContainer.inputcontainer.select - select#ulmer(name='ulmer') - option(selected='') — - option A+ - option A - option B+ - option B - option C - option D - option Z (What am I doing with my life?!) - label.input_separator(for='ulmer') -list - .form-group - label(for='income') Income - #incomeContainer.inputcontainer.select - select#income(name='income') - option(selected='') — - option Less than $20,000 - option $20,000–$30,000 - option $30,000–$40,000 - option $40,000–$50,000 - option $50,000–$60,000 - option $60,000–$70,000 - option $70,000–$80,000 - option $80,000–$100,000 - option $100,000–$150,000 - option $150,000–$250,000 - option $250,000–$500,000 - option $500,000–$1,000,000 - option More than $1,000,000 - option Rather not say - .form-group - label(for='relationshipStatus') Relationship Status - #relationshipStatusContainer.inputcontainer.select.autowidth - select#relationshipStatus(name='relationshipStatus') - option(selected='') Its complicated - option Single - option Seeing someone - option Married - option In an open relationship - .form-group - label(for='monogamous') Relationship Type - #monogamyFlexContainer.inputcontainer.select - select#monogamyFlex(name='monogamyFlex') - option — - option Mostly - option Strictly - #monogamousContainer.inputcontainer.select - select#monogamous(name='monogamous') - option — - option monogamous - option non-monogamous - .form-group - label(for='childrenQ1') Offspring - #childrenQ1Container.inputcontainer.select - select#childrenQ1(name='children') - option(selected='') — - option Has a kid - option Has kids - option Doesn’t have kids - #childrenQ2Container.inputcontainer.select - select#childrenQ2(name='children2') - option(selected='') — - option Might want kids - option Wants kids - option Doesn’t want kids - .form-group - label(for='dogs') Pets - #dogsContainer.inputcontainer.select - select#dogs(name='dogs') - option(selected='') — - option Has dogs - option Likes dogs - option Dislikes dogs - #catsContainer.inputcontainer.select - select#cats(name='cats') - option(selected='') — - option Has cats - option Likes cats - option Dislikes cats - // MODAL FOOTER - .modal-footer - button.btn.btn-default(type='button', data-dismiss='modal') Close - button.btn.btn-success(type='button') Save changes +// TRIGGER +button.btn.btn-primary-btn-sm(data-toggle='modal', data-target='#editDetails'): i.fa.fa-edit +// MODAL +#editDetails.modal.fade(tabindex='-1', role='dialog', aria-labelledby='editDetailsLabel', aria-hidden='true') + .modal-dialog.modal-lg + .modal-content + .modal-header + button.close(type='button', data-dismiss='modal') + span(aria-hidden='true') × + span.sr-only Close + h4#editDetailsLabel.modal-title Edit your details + .modal-body + form.form-horizontal#details_form(role='form', method='post', action='/profile/details') + input(type='hidden', name='_method', value='put') + .form-group + label.col-lg-2.control-label(for='orientation') Orientation + .col-lg-10 + select#orientation.form-control + option(selected='') - + option Asexual + option Bisexual + option Exploring + option Gay + option Heterosexual / Straight + br + .form-group + label.col-lg-2.control-label(for='ethnicities') Ethnicity + .col-lg-3 + label.checkbox(for='ethnicity1') + input#ethnicity1(type='checkbox', name='ethnicities') + span.icon + | Asian + label.checkbox(for='ethnicity2') + input#ethnicity2(type='checkbox', name='ethnicities') + span.icon + | Middle Eastern + label.checkbox(for='ethnicity3') + input#ethnicity3(type='checkbox', name='ethnicities') + span.icon + | Black + .col-lg-3 + label.checkbox(for='ethnicity4') + input#ethnicity4(type='checkbox', name='ethnicities') + span.icon + | Native American + label.checkbox(for='ethnicity5') + input#ethnicity5(type='checkbox', name='ethnicities') + span.icon + | Indian + label.checkbox(for='ethnicity6') + input#ethnicity6(type='checkbox', name='ethnicities') + span.icon + | Pacific Islander + .col-lg-3 + label.checkbox(for='ethnicity7') + input#ethnicity7(type='checkbox', name='ethnicities') + span.icon + | Hispanic / Latin + label.checkbox(for='ethnicity8') + input#ethnicity8(type='checkbox', name='ethnicities') + span.icon + | White + label.checkbox(for='ethnicity9') + input#ethnicity9(type='checkbox', name='ethnicities') + span.icon + | Other + .form-group + label.col-lg-2.control-label(for='feet') Height + #feetContainer.inputcontainer.select + select#feet(name='feet') + option — + option 7 + option 6 + option 5 + option 4 + option 3 + label.input_separator(for='feet') feet + #inchesContainer.inputcontainer.select + select#inches(name='inches') + option 0 + option 1 + option 2 + option 3 + option 4 + option 5 + option 6 + option 7 + option 8 + option 9 + option 10 + option 11 + label.input_separator(for='inches') inches + .form-group + label(for='bodyType') Body Type + #bodyTypeContainer.inputcontainer.select + select#bodyType(name='bodyType') + option(selected='') — + option Rather not say + option Thin + option Overweight + option Skinny + option Average + option Fit + option Athletic + option Jacked + option A little extra + option Curvy + option Full figured + option Used up + .form-group + label(for='diet') Diet + #dietContainer.inputcontainer.select + select#diet(name='diet') + option — + option anything + option halal + option kosher + option vegan + option vegetarian + option other + #dietSeriousContainer.inputcontainer.select + select#dietSerious(name='dietSerious') + option — + option Mostly + option Strictly + .form-group + label(for='smoking') Smokes + #smokingContainer.inputcontainer.select + select#smoking(name='smoking') + option(selected='') — + option Yes + option Sometimes + option When drinking + option Trying to quit + option No + .form-group + label(for='drinking') Drinks + #drinkingContainer.inputcontainer.select + select#drinking(name='drinking') + option(selected='') — + option Very often + option Often + option Socially + option Rarely + option Desperately + option Not at all + .form-group + label(for='drug') Drug of Choice + #drugContainer.inputcontainer.select + select#drug(name='drug') + option(selected='') — + optgroup(label='Narcotics') + option Heroin + option Hydromorphone + option Methadone + option Morphine + option Opium + option Oxycodone + optgroup(label='Stimulants') + option Amphetamines + option Cocaine + option Khat + option Methamphetamine + optgroup(label='Depressants') + option Barbiturates + option Benzodiazepines + option GHB + option Rohypnol + optgroup(label='Hallucinogens') + option Ecstasy / MDMA + option K2 / Spice + option Ketamine + option LSD + option Peyote & Mescaline + option Psilocybin + option Marijuana / Cannabis + option Steroids + option Inhalants + optgroup(label='Other') + option Bath Salts / Designer Cathinones + option DXM + option Salvia Divinorum + .form-group + label(for='religion') Religion + #religionContainer.inputcontainer.select + select#religion(name='religion') + option(selected='') — + option Agnosticism + option Atheism + option Christianity + option Judaism + option Catholicism + option Islam + option Hinduism + option Buddhism + option Other + #religionSeriousContainer.inputcontainer.select + select#religionSerious(name='religionSerious') + option(selected='') — + option and very serious about it + option and somewhat serious about it + option but not too serious about it + option and laughing about it + .form-group + label(for='sign') Sign + #signContainer.inputcontainer.select + select#sign(name='sign') + option(selected='') — + option Aquarius + option Pisces + option Aries + option Taurus + option Gemini + option Cancer + option Leo + option Virgo + option Libra + option Scorpio + option Sagittarius + option Capricorn + .form-group + label(for='educationStatus') Education + #educationStatusContainer.inputcontainer.select + select#educationStatus(name='educationStatus') + option(selected='') — + option Graduated from + option Working on + option Dropped out of + #educationLevelContainer.inputcontainer.select + select#educationLevel(name='educationLevel') + option(selected='') — + option high school + option acting school + option two-year college + option university + option masters program + option law school + option med school + option Ph.D program + option space camp + option school of hard knocks + .form-group + label(for='job') Ulmer Status + #ulmerContainer.inputcontainer.select + select#ulmer(name='ulmer') + option(selected='') — + option A+ + option A + option B+ + option B + option C + option D + option Z (What am I doing with my life?!) + label.input_separator(for='ulmer')-List + .form-group + label(for='income') Income + #incomeContainer.inputcontainer.select + select#income(name='income') + option(selected='') — + option Less than $20,000 + option $20,000–$30,000 + option $30,000–$40,000 + option $40,000–$50,000 + option $50,000–$60,000 + option $60,000–$70,000 + option $70,000–$80,000 + option $80,000–$100,000 + option $100,000–$150,000 + option $150,000–$250,000 + option $250,000–$500,000 + option $500,000–$1,000,000 + option More than $1,000,000 + option Rather not say + .form-group + label(for='relationshipStatus') Relationship Status + #relationshipStatusContainer.inputcontainer.select.autowidth + select#relationshipStatus(name='relationshipStatus') + option(selected='') Its complicated + option Single + option Seeing someone + option Married + option In an open relationship + .form-group + label(for='monogamous') Relationship Type + #monogamyFlexContainer.inputcontainer.select + select#monogamyFlex(name='monogamyFlex') + option — + option Mostly + option Strictly + #monogamousContainer.inputcontainer.select + select#monogamous(name='monogamous') + option — + option monogamous + option non-monogamous + .form-group + label(for='childrenQ1') Offspring + #childrenQ1Container.inputcontainer.select + select#childrenQ1(name='children') + option(selected='') — + option Has a kid + option Has kids + option Doesn’t have kids + #childrenQ2Container.inputcontainer.select + select#childrenQ2(name='children2') + option(selected='') — + option Might want kids + option Wants kids + option Doesn’t want kids + .form-group + label(for='dogs') Pets + #dogsContainer.inputcontainer.select + select#dogs(name='dogs') + option(selected='') — + option Has dogs + option Likes dogs + option Dislikes dogs + #catsContainer.inputcontainer.select + select#cats(name='cats') + option(selected='') — + option Has cats + option Likes cats + option Dislikes cats + .modal-footer + button.btn.btn-default(type='button', data-dismiss='modal') Close + button.btn.btn-success(type='submit') Save changes diff --git a/app/views/users/gifts.jade b/app/views/users/gifts.jade new file mode 100644 index 0000000..b448baf --- /dev/null +++ b/app/views/users/gifts.jade @@ -0,0 +1,25 @@ +extends ../shared/template +block content + .row + .col-xs-6.col-xs-offset-3.gifts + table#index.table.table-bordered.table-hover + thead + th Name + th Photo + th Price + tbody + each gift in gifts + tr + td + form(method='post', action='/cart') + input(type='hidden', name='giftId', value=gift._id) + button.btn.btn-default.btn-(data-toggle='modal', data-target='#gift')= gift.name + include checkout + td#giftImg + img(src=gift.photo) + td $#{gift.price.toFixed(2)} + .col-xs-3 + + +block scripts + diff --git a/app/views/users/inbox.jade b/app/views/users/inbox.jade new file mode 100644 index 0000000..b6d960e --- /dev/null +++ b/app/views/users/inbox.jade @@ -0,0 +1,51 @@ +extends ../shared/template +block content + .row + .col-xs-12 + .panel.panel-primary + .panel-heading + h3.panel-title Messages + .panel-body + .table-responsive + table.table.table-hover.table-bordered#messagesTable + thead + th From + th Date + th Message + tbody + each msg in msgs + tr(style='background-color:#{msg.isRead ? "#ECECEC" : "#8C8A8D"}') + td: a(href='/users/#{msg.sender.email}')= msg.sender.name + td= msg.date.toDateString() + td: a(href='/messages/#{msg._id}')= (msg.message.slice(0, 20) + ' .....') + .col-xs-12 + .row + .col-xs-6 + .panel.panel-primary + .panel-heading + h3.panel-title Proposals + .panel-body + .table-responsive + table.table.table-hover.table-bordered#proposalsTable + thead + th From + th Date + th Activity + th Message + tbody + each msg in msgs + tr(style='background-color:#{msg.isRead ? "#ECECEC" : "#8C8A8D"}') + td: a(href='/users/#{msg.sender.email}')= msg.sender.name + td= msg.date.toDateString() + td: a(href='/messages/#{msg._id}')= (msg.message.slice(0, 20) + ' .....') + .col-xs-6 + .panel.panel-primary + .panel-heading + h3.panel-title Proposals + .panel-body + .table-responsive + table.table.table-hover.table-bordered#proposalsTable + thead + th From + +block scripts diff --git a/app/views/users/init-info.jade b/app/views/users/init-info.jade new file mode 100644 index 0000000..9f49975 --- /dev/null +++ b/app/views/users/init-info.jade @@ -0,0 +1,29 @@ +extends ../shared/template +block content + h2 Tell Everyone A Litle About Yourself + .row + .col-xs-6 + form(role='form', method='post', action='/profile/init') + input(type='hidden', name='_method', value='put') + input(type='hidden', name='coordinates', data-name='lat') + input(type='hidden', name='coordinates', data-name='lng') + input(type='hidden', name='location', data-name='loc') + .form-group + label Alias (How you will Appear to other users) + input.form-control(type='text', name='alias', placeholder='AlisterISwear', autofocus=true) + .form-group + label Email + input.form-control(type='email', name='email', placeholder='bob@aol.com', value=user.email) + .form-group + label Phone + input.form-control(type='text', name='phone', placeholder='xxx-xxx-xxxx') + .form-group + label Zip (Where You Are) + input.form-control(type='text', name='zip') + button.btn.btn-success(type='submit') Submit + .col-xs-6 + +block scripts + script(src='https://maps.googleapis.com/maps/api/js?key=AIzaSyDOKBptUxmWBtYmtT8hfD67-TcrUhu4cl8&sensor=true') + script(src='/js/user/init-info.js') + diff --git a/app/views/users/login.jade b/app/views/users/login.jade index 63c5a1f..0769bee 100644 --- a/app/views/users/login.jade +++ b/app/views/users/login.jade @@ -2,7 +2,7 @@ extends ../shared/template block content h2 Login .row - .col-xs-6 + .col-xs-4.col-xs-offset-4 form(role='form', method='post', action='/login') .form-group label(for='email') Email @@ -11,7 +11,7 @@ block content label(for='password') Password input.form-control#password(type='password', name='password') button.btn.btn-success(type='submit') Submit - .col-xs-6 + .col-xs-4 block scripts diff --git a/app/views/users/message.jade b/app/views/users/message.jade new file mode 100644 index 0000000..c225e29 --- /dev/null +++ b/app/views/users/message.jade @@ -0,0 +1,17 @@ +extends ../shared/template +block content + .row + .col-xs-12 + h3 Message from sender.name + .panel.panel-success + .panel-body + p Date + h4 msg.message + .col-xs-12 + .row + .col-xs-4 + button.btn.btn-default.btn-(data-toggle='modal', data-target='#replymessage') Reply + include replymessage + + +block scripts diff --git a/app/views/users/messages.jade b/app/views/users/messages.jade new file mode 100644 index 0000000..e340ed5 --- /dev/null +++ b/app/views/users/messages.jade @@ -0,0 +1,54 @@ +extends ../shared/template +block content + .row + .col-xs-12 + .panel.panel-success + .panel-heading + h3.panel-title Messages + .panel-body + .table-responsive + table.table.table-hover.table-bordered#messagesTable + thead + th From + th Date + th Message + tbody + each msg in msgs + tr(style='background-color:#{msg.isRead ? "#ECECEC" : "#8C8A8D"}') + td: a(href='/users/#{msg.sender.email}')= msg.sender.name + td= msg.date.toDateString() + td: a(href='/messages/#{msg._id}')= (msg.message.slice(0, 20) + ' .....') + .col-xs-12 + .row + .col-xs-9 + .panel.panel-info + .panel-heading + h3.panel-title Date Proposals + .panel-body + .table-responsive + table.table.table-hover.table-bordered#proposalsTable + thead + th From + th Date + th Activity + th Message + tbody + tr + td + td + td + td + .col-xs-3 + .panel.panel-danger + .panel-heading + h3.panel-title Winks + .panel-body + .table-responsive + table.table.table-hover.table-bordered#winksTable + thead + th From + tbody + tr + td + +block scripts diff --git a/app/views/users/new.jade b/app/views/users/new.jade index 449a77e..75f9282 100644 --- a/app/views/users/new.jade +++ b/app/views/users/new.jade @@ -2,7 +2,7 @@ extends ../shared/template block content h2 Register .row - .col-xs-6 + .col-xs-4.col-xs-offset-4 form(role='form', method='post', action='/register') .form-group label(for='email') Email diff --git a/app/views/users/newMessage.jade b/app/views/users/newMessage.jade new file mode 100644 index 0000000..f5d53ca --- /dev/null +++ b/app/views/users/newMessage.jade @@ -0,0 +1,10 @@ +#newMessage.modal.fade(tabindex='-1', role='dialog', aria-labelledby='messageLabel', aria-hidden='true') + .modal-dialog + .modal-content + .modal-header + button.close(type='button', data-dismiss='modal', aria-hidden='true') × + h4.modal-title Send a Message + textarea.modal-body + .modal-footer + button.btn.btn-default(type='button', data-dismiss='modal') Close + button.btn.btn-primary(type='button') Send diff --git a/app/views/users/profile.jade b/app/views/users/profile.jade index d5b308a..9874520 100644 --- a/app/views/users/profile.jade +++ b/app/views/users/profile.jade @@ -1,8 +1,55 @@ extends ../shared/template block content - h2 Profile - .panel.panel-default - .panel-body - a(href='profile/edit') Edit Profile + .row + .col-xs-12 + .panel.panel-default + .panel-body + .row + .col-xs-2 + a.thumbnail#profile(href='/profile/photos') + img(src='/img/node.png') + .col-xs-6 + a(href='/profile/about') + h2=user.alias + ul.list-inline + li + h5=user.age + li + h5=user.gender + li + h5=user.address + .col-xs-2 + + .row + .col-xs-6 + .row + .col-xs-12 + .panel.panel-info + .panel-heading + h3#contact.panel-title Contact Information + include contact + .panel-body + h6 NOTE: This is the contact information section of the profile page. + .row + .col-xs-12 + .panel.panel-info + .panel-heading + h3#about.panel-title About Me + include about + .panel-body + h6 NOTE: This is the about section of the profile page. + .col-xs-6 + .row + .col-xs-12 + .panel.panel-info + .panel-heading + h3#details.panel-title Details + include details + .panel-body + h6 NOTE: This is the details section of the profile page. + + + + block scripts diff --git a/app/views/users/replymessage.jade b/app/views/users/replymessage.jade new file mode 100644 index 0000000..0cc36a0 --- /dev/null +++ b/app/views/users/replymessage.jade @@ -0,0 +1,10 @@ +#replymessage.modal.fade(tabindex='-1', role='dialog', aria-labelledby='messageLabel', aria-hidden='true') + .modal-dialog + .modal-content + .modal-header + button.close(type='button', data-dismiss='modal', aria-hidden='true') × + h4.modal-title Reply + textarea.modal-body + .modal-footer + button.btn.btn-default(type='button', data-dismiss='modal') Close + button.btn.btn-primary(type='button') Send diff --git a/db/gifts.json b/db/gifts.json new file mode 100644 index 0000000..148f752 --- /dev/null +++ b/db/gifts.json @@ -0,0 +1,30 @@ +{ + "_id" : ObjectId("000000000000000000000001"), + "name" : "Cowboy Hat", + "photo" : "http://kevinunderhill.typepad.com/.a/6a00d83451bd4469e201901e2db724970b-pi", + "price" : 75 +} +{ + "_id" : ObjectId("000000000000000000000002"), + "name" : "coffee mug", + "photo" : "http://ecx.images-amazon.com/images/I/41KwWFJNfTL.jpg", + "price" : 3.5 +} +{ + "_id" : ObjectId("000000000000000000000003"), + "name" : "iPhone5", + "photo" : "http://www.hdwallpapersinn.com/wp-content/uploads/2014/07/iphone_5_folders_hero.jpg", + "price" : 299 +} +{ + "_id" : ObjectId("000000000000000000000004"), + "name" : "Buffy the Vampire Slayer Box Set", + "photo" : "http://www.dvdspecialonline.com/product_images/d/228/buffy-1-7-2__92479_zoom.jpg", + "price" : 100 +} +{ + "_id" : ObjectId("000000000000000000000005"), + "name" : "West Wing Box Set", + "photo" : "http://www.tvshowsondvd.com/graphics/news3/WestWingComplete-Inside.jpg", + "price" : 105 +} diff --git a/db/messages.json b/db/messages.json new file mode 100644 index 0000000..a16308b --- /dev/null +++ b/db/messages.json @@ -0,0 +1,16 @@ +{ + "_id":{"$oid":"c00000000000000000000001"}, + "senderId":{"$oid":"000000000000000000000002"}, + "receiverId":{"$oid":"000000000000000000000001"}, + "message":"test message", + "date":{"$date":1409541250448}, + "isRead":false +} +{ + "_id":{"$oid":"c00000000000000000000002"}, + "senderId":{"$oid":"000000000000000000000002"}, + "receiverId":{"$oid":"000000000000000000000001"}, + "message":"test message 2", + "date":{"$date":1409541250448}, + "isRead":true +} diff --git a/db/users.json b/db/users.json index 41a8e89..c27c70d 100644 --- a/db/users.json +++ b/db/users.json @@ -1,11 +1,51 @@ { "_id" : {"$oid":"000000000000000000000001"}, - "email" : "bob@aol.com", - "password" : "$2a$10$XR.IQktUUujLBxed70GQn.jWY1wZ9ThM0Tar9wTqzkI4Uk1uP2Or2" + "coordinates" : [36.1003494, -86.77180169999997], + "email" : "bob@mailinator.com", + "password" : "$2a$10$ZvS/Y7WPMK5DLSVZwDaq3euj.WIzSDJsgGkMaQUZg/YYCU7kuzicy", + "type" : "local", + "alias" : "BobBoberson", + "location" : "Nashville, TN 37204, USA", + "phone" : "316-650-0346", + "zip" : "37204", + "photos" : [{url:'photo1.jpg', isPrimary:true}, {url:'photo2.jpg', isPrimary:false}, {url:'photo3.jpg', isPrimary:false}] } { "_id" : {"$oid":"000000000000000000000002"}, - "email" : "sue@aol.com", - "password" : "$2a$10$sjPx9TkrEASeXzH6uuDCDO.n1Sj/H2A/bu/9hBFfm5fm3Z4LzrEPa" + "coordinates" : [36.1724885, -86.78059610000003], + "email" : "sue@mailinator.com", + "password" : "$2a$10$FpmjBzpoRgl2upGrwhNFAOKTOqFifZeYAPZ8BssCLGbRxhxf9Bafy", + "type" : "local", + "alias" : "SueJones", + "location" : "Nashville, TN 37201, USA", + "phone" : "316-650-0346", + "zip" : "37201" +} +{ + "_id" : {"$oid":"000000000000000000000003"}, + "coordinates" : [39.6487896, -105.0148322], + "googleId" : "000000000000000000001", + "type" : "google", + "alias" : "JohnJohnson", + "email" : "john@mailinator.com", + "location" : "Englewood, CO 80110, USA", + "phone" : "316-650-0346", + "zip" : "80110", + "photos" : [{url:'photo1.jpg', isPrimary:true}, {url:'photo2.jpg', isPrimary:false}, {url:'photo3.jpg', isPrimary:false}] +} +{ + "_id" : {"$oid":"000000000000000000000004"}, + "coordinates" : [33.9697897, -118.2468148], + "facebookId" : "90000000000000001", + "type" : "facebook", + "alias" : "JenJohnson", + "email" : "jen@mailinator.com", + "location" : "Los Angeles, CA 90001, USA", + "phone" : "316-650-0346", + "zip" : "90001" +} +{ + "_id" : {"$oid":"000000000000000000000005"}, + "facebookId" : "90000000000000002", + "type" : "facebook" } - diff --git a/test/acceptance/users.js b/test/acceptance/users.js index 35dd00b..7c53209 100644 --- a/test/acceptance/users.js +++ b/test/acceptance/users.js @@ -2,7 +2,7 @@ 'use strict'; -process.env.DB = 'template-test'; +process.env.DB = 'celebridate-test'; var expect = require('chai').expect, cp = require('child_process'), @@ -19,7 +19,7 @@ describe('users', function(){ cp.execFile(__dirname + '/../scripts/clean-db.sh', [process.env.DB], {cwd:__dirname + '/../scripts'}, function(err, stdout, stderr){ request(app) .post('/login') - .send('email=bob@aol.com') + .send('email=bob@mailinator.com') .send('password=1234') .end(function(err, res){ cookie = res.headers['set-cookie'][0]; @@ -54,7 +54,7 @@ describe('users', function(){ it('should redirect to the register page(duplicate email in system)', function(done){ request(app) .post('/register') - .send('email=bob%40aol.com&password=1234') + .send('email=bob%40mailinator.com&password=1234') .end(function(err, res){ expect(res.status).to.equal(302); expect(res.headers.location).to.equal('/register'); @@ -75,14 +75,62 @@ describe('users', function(){ }); }); + describe('get /auth/google', function(){ + it('should initiate oauth with google service', function(done){ + request(app) + .get('/auth/google') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location.indexOf('accounts.google.com')).to.not.equal(-1); + done(); + }); + }); + }); + + describe('get /auth/google/callback', function(){ + it('should trigger passport function', function(done){ + request(app) + .get('/auth/google/callback') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location.indexOf('accounts.google.com')).to.not.equal(-1); + done(); + }); + }); + }); + + describe('get /auth/facebook', function(){ + it('should initiate oauth with facebook service', function(done){ + request(app) + .get('/auth/facebook') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location.indexOf('facebook')).to.not.equal(-1); + done(); + }); + }); + }); + + describe('get /auth/facebook/callback', function(){ + it('should initiate oauth with facebook service', function(done){ + request(app) + .get('/auth/facebook/callback') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location.indexOf('facebook')).to.not.equal(-1); + done(); + }); + }); + }); + describe('post /login', function(){ it('should redirect to the home page', function(done){ request(app) .post('/login') - .send('email=bob%40aol.com&password=1234') + .send('email=bob%40mailinator.com&password=1234') .end(function(err, res){ expect(res.status).to.equal(302); - expect(res.headers.location).to.equal('/profile'); + expect(res.headers.location).to.equal('/verify'); done(); }); }); @@ -125,5 +173,114 @@ describe('users', function(){ }); }); + describe('get /profile', function(){ + it('should display the user\'s profile page', function(done){ + request(app) + .get('/profile') + .set('cookie', cookie) + .end(function(err, res){ + expect(res.status).to.equal(200); + expect(res.text).to.include('Profile'); + expect(res.text).to.include('About Me'); + done(); + }); + }); + }); + + describe('get /messages', function(){ + it('should return the messages page', function(done){ + request(app) + .get('/messages') + .set('cookie', cookie) + .end(function(err, res){ + expect(res.status).to.equal(200); + expect(res.text).to.include('Message'); + done(); + }); + }); + }); + + describe('put /profile/photos/primary', function(){ + it('should redirect to profile after setting primary profile photo', function(done){ + request(app) + .post('/profile/photos/primary') + .set('cookie', cookie) + .send('_method=put&index=1') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location).to.equal('/profile'); + done(); + }); + }); + }); + + describe('put /profile/about', function(){ + it('should redirect to profile after updating about info', function(done){ + request(app) + .post('/profile/about') + .set('cookie', cookie) + .send('_method=put&summary=Test') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location).to.equal('/profile'); + done(); + }); + }); + }); + + describe('put /profile/about', function(){ + it('should redirect to profile after updating about info', function(done){ + request(app) + .post('/profile/about') + .set('cookie', cookie) + .send('_method=put&summary=Test') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location).to.equal('/profile'); + done(); + }); + }); + }); + + describe('put /profile/details', function(){ + it('should redirect to profile after updating details info', function(done){ + request(app) + .post('/profile/details') + .set('cookie', cookie) + .send('_method=put&bodyType=thin') + .end(function(err, res){ + expect(res.status).to.equal(302); + expect(res.headers.location).to.equal('/profile'); + done(); + }); + }); + }); + + describe('get /messages/messageId', function(){ + it('should return a message for the user', function(done){ + request(app) + .get('/messages/c00000000000000000000001') + .set('cookie', cookie) + .end(function(err, res){ + expect(res.status).to.equal(200); + expect(res.text).to.include('message'); + done(); + }); + }); + }); + + describe('get /messages/messageId', function(){ + it('should return a message for the user', function(done){ + request(app) + .get('/messages/c00000000000000000000001') + .set('cookie', cookie) + .end(function(err, res){ + expect(res.status).to.equal(200); + expect(res.text).to.include('message'); + done(); + }); + }); + }); + }); diff --git a/test/img/.gitkeep b/test/img/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/img/test1.jpg b/test/img/test1.jpg new file mode 100644 index 0000000..e69de29 diff --git a/test/img/test2.jpg b/test/img/test2.jpg new file mode 100644 index 0000000..e69de29 diff --git a/test/scripts/clean-db.sh b/test/scripts/clean-db.sh index 55e6db7..51ae681 100755 --- a/test/scripts/clean-db.sh +++ b/test/scripts/clean-db.sh @@ -5,6 +5,7 @@ if [ -z "$1" ] ; then exit 1 fi -mongoimport --jsonArray --drop --db $1 --collection examples --file ../../db/example.json +mongoimport --jsonArray --drop --db $1 --collection gifts --file ../../db/gifts.json mongoimport --jsonArray --drop --db $1 --collection users --file ../../db/users.json +mongoimport --jsonArray --drop --db $1 --collection messages --file ../../db/messages.json diff --git a/test/scripts/make-img.sh b/test/scripts/make-img.sh new file mode 100755 index 0000000..3b794f3 --- /dev/null +++ b/test/scripts/make-img.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +rm -rf ../../app/static/img/user_pics/0000000000000* +touch ../img/test1.jpg +touch ../img/test2.jpg + diff --git a/test/unit/user.js b/test/unit/user.js index 78ca480..2f87c39 100644 --- a/test/unit/user.js +++ b/test/unit/user.js @@ -1,13 +1,14 @@ /* jshint expr:true */ -/* global describe, it, before, beforeEach */ +/* global describe, it, before, beforeEach, after */ 'use strict'; var expect = require('chai').expect, User = require('../../app/models/user'), + Mongo = require('mongodb'), dbConnect = require('../../app/lib/mongodb'), cp = require('child_process'), - db = 'template-test'; + db = 'celebridate-test'; describe('User', function(){ before(function(done){ @@ -18,6 +19,14 @@ describe('User', function(){ beforeEach(function(done){ cp.execFile(__dirname + '/../scripts/clean-db.sh', [db], {cwd:__dirname + '/../scripts'}, function(err, stdout, stderr){ + cp.execFile(__dirname + '/../scripts/make-img.sh', [], {cwd:__dirname + '/../scripts'}, function(err, stdout, stderr){ + done(); + }); + }); + }); + + after(function(done){ + cp.execFile(__dirname + '/../scripts/make-img.sh', [], {cwd:__dirname + '/../scripts'}, function(err, stdout, stderr){ done(); }); }); @@ -26,7 +35,125 @@ describe('User', function(){ it('should create a new User object', function(){ var u = new User(); expect(u).to.be.instanceof(User); + expect(u.coordinates).to.have.length(0); + }); + }); + + describe('.findByIdSession', function(){ + it('should return a user object with limited fields', function(done){ + User.findByIdSession('000000000000000000000002', function(err, u){ + expect(Object.keys(u)).to.have.length(7); + expect(u).to.respondTo('moveFiles'); + expect(u._id.toString()).to.equal('000000000000000000000002'); + done(); + }); + }); + }); + + describe('.findById', function(){ + it('should return a full user object from the database', function(done){ + User.findById('000000000000000000000002', function(err, u){ + expect(u).to.respondTo('moveFiles'); + expect(u._id.toString()).to.equal('000000000000000000000002'); + expect(Object.keys(u).length).to.be.at.least(7); + done(); + }); + }); + }); + + describe('.googleAuth', function(){ + it('should create a new user in DB', function(done){ + var obj = {id:'0009090'}; + User.googleAuth({}, {}, obj, function(err, u){ + expect(u._id).to.be.instanceof(Mongo.ObjectID); + done(); + }); }); }); + + describe('.facebookAuth', function(){ + it('should create a new user in DB', function(done){ + var obj = {id:'9090909'}; + User.facebookAuth({}, {}, obj, function(err, u){ + expect(u._id).to.be.instanceof(Mongo.ObjectID); + done(); + }); + }); + }); + + describe('.addPhotos', function(){ + it('should move & rename files uploaded by user', function(done){ + var test1 = __dirname + '/../img/test1.jpg', + test2 = __dirname + '/../img/test2.jpg', + files = {photos: [{size:'5kb', path:test1}, {size:'5kb', path:test2}]}; + console.log(test1, test2); + User.findById('000000000000000000000002', function(err, u){ + User.addPhotos(u, files, function(){ + User.findById('000000000000000000000002', function(err2, u2){ + expect(u2.photos).to.have.length(2); + done(); + }); + }); + }); + }); + }); + + describe('#initUpdate', function(){ + it('should add required initial info to a new user & update record in database', function(done){ + User.findById('000000000000000000000005', function(err, u){ + var data = {alias:'SweetJonney', email:'sw@mailinator.com', location:'Nashville, TN 37201, USA', coordinates:['0', '0'], phone:'555-555-5555', zip:'99999'}; + u.initUpdate(data, function(){ + User.findById('000000000000000000000005', function(err2, u2){ + expect(u2.alias).to.equal('SweetJonney'); + expect(u2.coordinates[0]).to.equal(0); + done(); + }); + }); + }); + }); + }); + + describe('#updateAbout', function(){ + it('should update the user\'s about informaion', function(done){ + User.findById('000000000000000000000005', function(err, u){ + var data = {summary:'I\'m a lonely celebrity', favoriteStuff:'Being famous'}; + u.updateAbout(data, function(){ + User.findById('000000000000000000000005', function(err2, u2){ + expect(u2.about.summary).to.equal('I\'m a lonely celebrity'); + done(); + }); + }); + }); + }); + }); + + describe('#updateDetails', function(){ + it('should update the user\'s detail informaion', function(done){ + User.findById('000000000000000000000005', function(err, u){ + var data = {drugs:'Always', diet:'cocain', bodyType:'thin'}; + u.updateDetails(data, function(){ + User.findById('000000000000000000000005', function(err2, u2){ + expect(u2.details.diet).to.equal('cocain'); + done(); + }); + }); + }); + }); + }); + + describe('#setProfilePhoto', function(){ + it('should mark a photo in photos array to primary', function(done){ + User.findById('000000000000000000000003', function(err, u){ + u.setProfilePhoto('2', function(){ + User.findById('000000000000000000000003', function(err2, u2){ + expect(u2.photos[0].isPrimary).to.equal(false); + expect(u2.photos[2].isPrimary).to.equal(true); + done(); + }); + }); + }); + }); + }); + });