public profile accessible and start updating form

This commit is contained in:
Michael Q Larson
2015-01-05 16:38:56 -08:00
parent ba037abe53
commit db9622a2e5
6 changed files with 224 additions and 50 deletions

4
app.js
View File

@ -243,6 +243,10 @@ app.get(
'/challenges/:challengeNumber', '/challenges/:challengeNumber',
challengesController.returnChallenge challengesController.returnChallenge
); );
app.get(
'/users/:username',
userController.returnUser
);
app.all('/account', passportConf.isAuthenticated); app.all('/account', passportConf.isAuthenticated);
app.get('/account', userController.getAccount); app.get('/account', userController.getAccount);
app.post('/account/profile', userController.postUpdateProfile); app.post('/account/profile', userController.postUpdateProfile);

View File

@ -1,14 +1,16 @@
var _ = require('lodash'); var _ = require('lodash'),
var async = require('async'); async = require('async'),
var crypto = require('crypto'); crypto = require('crypto'),
var nodemailer = require('nodemailer'); nodemailer = require('nodemailer'),
var passport = require('passport'); passport = require('passport'),
var User = require('../models/User'); User = require('../models/User'),
var secrets = require('../config/secrets'); secrets = require('../config/secrets'),
var moment = require('moment'); moment = require('moment'),
var Challenge = require('./../models/Challenge'); Challenge = require('./../models/Challenge'),
debug = require('debug')('freecc:cntr:challenges');
//TODO(Berks): Refactor to use module.exports = {} pattern. //TODO(Berks): Refactor to use module.exports = {} pattern.
/** /**
* GET /login * GET /login
* Login page. * Login page.
@ -148,6 +150,50 @@ exports.getAccount = function(req, res) {
}); });
}; };
/**
* GET /users/:username
* Public Profile page.
*/
exports.returnUser = function(req, res, next) {
User.find({'profile.username': req.params.username}, function(err, user) {
if (err) { debug('Username err: ', err); next(err); }
if (user[0]) {
var user = user[0];
Challenge.find({}, null, {sort: {challengeNumber: 1}}, function (err, c) {
res.render('account/show', {
title: 'Code Camper: ',
username: user.profile.username,
name: user.profile.name,
location: user.profile.location,
coderbyteProfile: user.profile.linkedinProfile,
githubProfile: user.profile.githubProfile,
linkedinProfile: user.profile.linkedinProfile,
website1: user.portfolio.website1Link,
website1Title: user.portfolio.website1Title,
website1Image: user.portfolio.website1Image,
website2: user.portfolio.website2Link,
website2Title: user.portfolio.website2Title,
website2Image: user.portfolio.website2Image,
website3: user.portfolio.website3Link,
website3Title: user.portfolio.website3Title,
website3Image: user.portfolio.website3Image,
picture: user.profile.picture,
challenges: c,
ch: user.challengesHash,
moment: moment
});
});
} else {
req.flash('errors', {
msg: "We couldn't find a Code Camper with that username."
});
return res.redirect('/');
}
});
};
/** /**
* POST /update-progress * POST /update-progress
* Update profile information. * Update profile information.
@ -217,6 +263,16 @@ exports.postUpdateProfile = function(req, res, next) {
user.profile.username = req.body.username || ''; user.profile.username = req.body.username || '';
user.profile.location = req.body.location || ''; user.profile.location = req.body.location || '';
user.profile.website = req.body.website || ''; user.profile.website = req.body.website || '';
user.portfolio.website1Title = req.body.website1Title || '';
user.portfolio.website1Link = req.body.website1Link || '';
user.portfolio.website1Image = req.body.website1Image || '';
user.portfolio.website2Title = req.body.website2Title || '';
user.portfolio.website2Link = req.body.website2Link || '';
user.portfolio.website2Image = req.body.website2Image || '';
user.portfolio.website3Title = req.body.website3Title || '';
user.portfolio.website3Link = req.body.website3Link || '';
user.portfolio.website3Image = req.body.website3Image || '';
user.save(function (err) { user.save(function (err) {
if (err) return next(err); if (err) return next(err);

View File

@ -6,6 +6,7 @@ var userSchema = new mongoose.Schema({
email: { email: {
type: String, type: String,
lowercase: true, lowercase: true,
unique: true,
trim: true trim: true
}, },
password: String, password: String,
@ -13,7 +14,6 @@ var userSchema = new mongoose.Schema({
twitter: String, twitter: String,
google: String, google: String,
github: String, github: String,
instagram: String,
linkedin: String, linkedin: String,
tokens: Array, tokens: Array,
points: { points: {
@ -264,6 +264,13 @@ var userSchema = new mongoose.Schema({
} }
}, },
profile: { profile: {
username: {
type: String,
default: '',
unique: true,
lowercase: true,
trim: true
},
name: { name: {
type: String, default: '' type: String, default: ''
}, },
@ -273,23 +280,59 @@ var userSchema = new mongoose.Schema({
location: { location: {
type: String, default: '' type: String, default: ''
}, },
website: {
type: String,
default: ''
},
picture: { picture: {
type: String, type: String,
default: '' default: ''
}, },
username: { linkedinProfile: {
type: String, default: ''
},
githubProfile: {
type: String, default: ''
},
coderbyteProfile: {
type: String, type: String,
default: '', default: ''
//unique: true, }
lowercase: true, },
trim: true portfolio: {
website1Link: {
type: String,
default: ''
},
website1Title: {
type: String,
default: ''
},
website1Image: {
type: String,
default: ''
},
website2Link: {
type: String,
default: ''
},
website2Title: {
type: String,
default: ''
},
website2Image: {
type: String,
default: ''
},
website3Link: {
type: String,
default: ''
},
website3Title: {
type: String,
default: ''
},
website3Image: {
type: String,
default: ''
} }
}, },
resetPasswordToken: String, resetPasswordToken: String,
resetPasswordExpires: Date resetPasswordExpires: Date
}); });

View File

@ -381,3 +381,8 @@ thead {
padding-top: 10px !important; padding-top: 10px !important;
padding-bottom: 10px !important; padding-bottom: 10px !important;
} }
.nameline {
margin-top: -5px;
font-size: 40px;
}

View File

@ -4,7 +4,6 @@ block content
.panel .panel
.container.text-center .container.text-center
h1 Update your profile here: h1 Update your profile here:
.animated.flipInX
form.form-horizontal(action='/account/profile', method='POST') form.form-horizontal(action='/account/profile', method='POST')
input(type='hidden', name='_csrf', value=_csrf) input(type='hidden', name='_csrf', value=_csrf)
.form-group .form-group
@ -23,10 +22,45 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='location') Location label.col-sm-3.col-sm-offset-2.control-label(for='location') Location
.col-sm-4 .col-sm-4
input.form-control(type='text', name='location', id='location', value='#{user.profile.location}') input.form-control(type='text', name='location', id='location', value='#{user.profile.location}')
.form-group .form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website') Website label.col-sm-3.col-sm-offset-2.control-label(for='website1Title') 1st Portfolio Website Title
.col-sm-4 .col-sm-4
input.form-control(type='text', name='website', id='website', value='#{user.profile.website}') input.form-control(type='text', name='website1Title', id='website1Title', value='#{user.portfolio.website1Title}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website1Link') 1st Portfolio Website Link
.col-sm-4
input.form-control(type='text', name='website1Link', id='website1Link', value='#{user.portfolio.website1Link}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website1Image') 1st Portfolio Website Image Link
.col-sm-4
input.form-control(type='text', name='website1Image', id='website1Image', value='#{user.portfolio.website1Image}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website2Title') 2nd Portfolio Website Title
.col-sm-4
input.form-control(type='text', name='website2Title', id='website2Title', value='#{user.portfolio.website2Title}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website2Link') 2nd Portfolio Website Link
.col-sm-4
input.form-control(type='text', name='website2Link', id='website2Link', value='#{user.portfolio.website2Link}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website2Image') 2nd Portfolio Website Image Link
.col-sm-4
input.form-control(type='text', name='website2Image', id='website2Image', value='#{user.portfolio.website2Image}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website3Title') 3rd Portfolio Website Title
.col-sm-4
input.form-control(type='text', name='website3Title', id='website3Title', value='#{user.portfolio.website3Title}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website3Link') 3rd Portfolio Website Link
.col-sm-4
input.form-control(type='text', name='website3Link', id='website3Link', value='#{user.portfolio.website3Link}')
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website3Image') 3rd Portfolio Website Image Link
.col-sm-4
input.form-control(type='text', name='website3Image', id='website3Image', value='#{user.portfolio.website3Image}')
.form-group .form-group
.col-sm-offset-2.col-sm-4 .col-sm-offset-2.col-sm-4
button.btn.btn.btn-primary(type='submit') button.btn.btn.btn-primary(type='submit')

32
views/account/show.jade Normal file
View File

@ -0,0 +1,32 @@
extends ../layout
block content
.panel.panel-primary
.panel-heading.text-center @#{username}
.panel-body
.row
.col-xs-2.col-sm-1.col-md-1
img(src="#{picture}")
.col-xs-4.col-sm-2.col-md-2
h2.nameline
= "[ " + user.points + " ]"
.col-xs-6.col-sm-9.col-md-9
h2.nameline
= name
h4= location
a(href="#{coderbyteProfile")
| Coderbyte Profile
- if (ch[0] > 0)
.container
h1 Completed Challenges
.col-xs-12
table.table.table-striped
thead
tr
th Challenge
th Date Finished
for challenge in challenges
if ch[challenge.challengeNumber] > 0
tr
td= challenges[challenge.challengeNumber].name
td= moment(ch[challenge.challengeNumber], 'X').format("MMM DD, YYYY")
br