public profile accessible and start updating form
This commit is contained in:
4
app.js
4
app.js
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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
32
views/account/show.jade
Normal 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
|
Reference in New Issue
Block a user