diff --git a/app/assets/javascripts/discourse/controllers/user_controller.js b/app/assets/javascripts/discourse/controllers/user_controller.js
index 65b036274..105419876 100644
--- a/app/assets/javascripts/discourse/controllers/user_controller.js
+++ b/app/assets/javascripts/discourse/controllers/user_controller.js
@@ -18,6 +18,10 @@ Discourse.UserController = Discourse.ObjectController.extend({
return this.get('viewingSelf') || Discourse.User.currentProp('admin');
}.property('viewingSelf'),
+ showBadges: function() {
+ return Discourse.SiteSettings.enable_badges;
+ }.property(),
+
privateMessageView: function() {
return (this.get('userActionType') === Discourse.UserAction.TYPES.messages_sent) ||
(this.get('userActionType') === Discourse.UserAction.TYPES.messages_received);
diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js
index 261b92917..fb739f585 100644
--- a/app/assets/javascripts/discourse/routes/application_routes.js
+++ b/app/assets/javascripts/discourse/routes/application_routes.js
@@ -78,6 +78,8 @@ Discourse.Route.buildRoutes(function() {
});
});
+ this.route('badges');
+
this.resource('userPrivateMessages', { path: '/private-messages' }, function() {
this.route('mine');
this.route('unread');
diff --git a/app/assets/javascripts/discourse/routes/user_badges_route.js b/app/assets/javascripts/discourse/routes/user_badges_route.js
new file mode 100644
index 000000000..97ad6ddf9
--- /dev/null
+++ b/app/assets/javascripts/discourse/routes/user_badges_route.js
@@ -0,0 +1,25 @@
+/**
+ This route shows a user's badges.
+
+ @class UserBadgesRoute
+ @extends Discourse.Route
+ @namespace Discourse
+ @module Discourse
+**/
+Discourse.UserBadgesRoute = Discourse.Route.extend({
+ model: function() {
+ return Discourse.UserBadge.findByUsername(this.modelFor('user').get('username_lower'));
+ },
+
+ setupController: function(controller, model) {
+ this.controllerFor('user').set('indexStream', false);
+ if (this.controllerFor('user_activity').get('content')) {
+ this.controllerFor('user_activity').set('userActionType', -1);
+ }
+ controller.set('model', model);
+ },
+
+ renderTemplate: function() {
+ this.render('user/badges', {into: 'user', outlet: 'userOutlet'});
+ }
+});
diff --git a/app/assets/javascripts/discourse/templates/user/badges.js.handlebars b/app/assets/javascripts/discourse/templates/user/badges.js.handlebars
new file mode 100644
index 000000000..6cbf2003c
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/user/badges.js.handlebars
@@ -0,0 +1,5 @@
+
+ {{#each}}
+ {{user-badge badge=badge}}
+ {{/each}}
+
diff --git a/app/assets/javascripts/discourse/templates/user/user.js.handlebars b/app/assets/javascripts/discourse/templates/user/user.js.handlebars
index 882f9999c..0cf25536a 100644
--- a/app/assets/javascripts/discourse/templates/user/user.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/user/user.js.handlebars
@@ -13,6 +13,16 @@
{{#each stat in statsExcludingPms}}
{{discourse-activity-filter content=stat user=model userActionType=userActionType indexStream=indexStream}}
{{/each}}
+ {{#if showBadges}}
+ {{#link-to 'user.badges' tagName="li"}}
+ {{#link-to 'user.badges'}}
+
+ {{i18n badges.title}}
+ ({{badge_count}})
+
+ {{/link-to}}
+ {{/link-to}}
+ {{/if}}
{{#if canSeePrivateMessages}}
diff --git a/app/assets/stylesheets/desktop/user-badges.scss b/app/assets/stylesheets/desktop/user-badges.scss
index 941e715a2..2be02acb1 100644
--- a/app/assets/stylesheets/desktop/user-badges.scss
+++ b/app/assets/stylesheets/desktop/user-badges.scss
@@ -1,3 +1,4 @@
+/* Default badge styles. */
.user-badge {
padding: 3px 8px;
color: $primary_text_color;
@@ -27,6 +28,26 @@
}
}
+/* User badge listing. */
+.user-badges-list {
+ text-align: center;
+
+ .user-badge {
+ max-width: 80px;
+ text-align: center;
+ vertical-align: top;
+ margin: 10px;
+ border: none;
+
+ .fa {
+ display: block;
+ font-size: 50px;
+ margin-bottom: 5px;
+ }
+ }
+}
+
+/* Badge listing in /badges. */
table.badges-listing {
margin: 20px 0;
border-bottom: 1px solid $primary-border-color;
diff --git a/config/routes.rb b/config/routes.rb
index 2bf6bfa35..bb3b6e64b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -195,6 +195,7 @@ Discourse::Application.routes.draw do
post "users/:username/send_activation_email" => "users#send_activation_email", constraints: {username: USERNAME_ROUTE_FORMAT}
get "users/:username/activity" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
get "users/:username/activity/:filter" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
+ get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
delete "users/:username" => "users#destroy", constraints: {username: USERNAME_ROUTE_FORMAT}
get "uploads/:site/:id/:sha.:extension" => "uploads#show", constraints: {site: /\w+/, id: /\d+/, sha: /[a-z0-9]{15,16}/i, extension: /\w{2,}/}