diff --git a/app/assets/javascripts/discourse/components/user-small.js.es6 b/app/assets/javascripts/discourse/components/user-small.js.es6
new file mode 100644
index 00000000000..fbbd65827f8
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/user-small.js.es6
@@ -0,0 +1,3 @@
+export default Ember.Component.extend({
+ classNames: ['user-small']
+});
diff --git a/app/assets/javascripts/discourse/routes/about.js.es6 b/app/assets/javascripts/discourse/routes/about.js.es6
new file mode 100644
index 00000000000..37f20b64507
--- /dev/null
+++ b/app/assets/javascripts/discourse/routes/about.js.es6
@@ -0,0 +1,8 @@
+export default Ember.Route.extend({
+ model: function() {
+ return Discourse.ajax("/about.json").then(function(result) {
+ return result.about;
+ });
+ }
+});
+
diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js
index e081b665c69..e2539177499 100644
--- a/app/assets/javascripts/discourse/routes/application_routes.js
+++ b/app/assets/javascripts/discourse/routes/application_routes.js
@@ -10,6 +10,8 @@ Discourse.Route.buildRoutes(function() {
// Error page
this.route('exception', { path: '/exception' });
+ this.resource('about', { path: '/about' });
+
// Topic routes
this.resource('topic', { path: '/t/:slug/:id' }, function() {
this.route('fromParams', { path: '/' });
diff --git a/app/assets/javascripts/discourse/templates/about.js.handlebars b/app/assets/javascripts/discourse/templates/about.js.handlebars
new file mode 100644
index 00000000000..7250a230836
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/about.js.handlebars
@@ -0,0 +1,62 @@
+
+
{{i18n about.title}}
+
+ {{#if admins}}
+
+ Our Admins
+
+ {{#each admins}}
+ {{user-small user=this}}
+ {{/each}}
+
+
+
+ {{/if}}
+
+ {{#if moderators}}
+
+ Our Moderators
+
+
+ {{#each moderators}}
+ {{user-small user=this}}
+ {{/each}}
+
+
+
+ {{/if}}
+
+
+ {{i18n about.stats}}
+
+
+
+ {{i18n about.topic_count}} |
+ {{stats.topic_count}} |
+
+
+ {{i18n about.topics_7_days}} |
+ {{stats.topics_7_days}} |
+
+
+ {{i18n about.post_count}} |
+ {{stats.post_count}} |
+
+
+ {{i18n about.posts_7_days}} |
+ {{stats.posts_7_days}} |
+
+
+ {{i18n about.user_count}} |
+ {{stats.user_count}} |
+
+
+ {{i18n about.users_7_days}} |
+ {{stats.users_7_days}} |
+
+
+
+
+
+
+
diff --git a/app/assets/javascripts/discourse/templates/components/user-small.js.handlebars b/app/assets/javascripts/discourse/templates/components/user-small.js.handlebars
new file mode 100644
index 00000000000..674f8f75905
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/user-small.js.handlebars
@@ -0,0 +1,4 @@
+{{#link-to 'user' user.username}}
+ {{avatar user imageSize="tiny"}}
+ {{user.username}}
+{{/link-to}}
diff --git a/app/assets/stylesheets/common/base/about.scss b/app/assets/stylesheets/common/base/about.scss
new file mode 100644
index 00000000000..4364d5f3df4
--- /dev/null
+++ b/app/assets/stylesheets/common/base/about.scss
@@ -0,0 +1,34 @@
+section.about {
+ margin-top: 20px;
+
+ h3 {
+ margin-bottom: 10px;
+ }
+
+ .user-small {
+ padding: 5px;
+ width: 200px;
+ float: left;
+
+ img {
+ padding-right: 4px;
+ }
+ }
+
+ padding-bottom: 10px;
+
+ table {
+ margin-top: 20px;
+ width: 100%;
+
+ td, th {
+ padding: 10px 5px 5px 5px;
+ border-bottom: 1px solid lighten($primary, 70%);
+ }
+
+ td.title {
+ width: 30%;
+ }
+
+ }
+}
diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb
new file mode 100644
index 00000000000..d1a0b3d0338
--- /dev/null
+++ b/app/controllers/about_controller.rb
@@ -0,0 +1,8 @@
+class AboutController < ApplicationController
+ skip_before_filter :check_xhr, only: [:show]
+
+ def index
+ @about = About.new
+ render_serialized(@about, AboutSerializer)
+ end
+end
diff --git a/app/models/about.rb b/app/models/about.rb
new file mode 100644
index 00000000000..4bc4b187835
--- /dev/null
+++ b/app/models/about.rb
@@ -0,0 +1,26 @@
+class About
+ include ActiveModel::Serialization
+
+ attr_accessor :moderators,
+ :admins
+
+ def moderators
+ @moderators ||= User.where(moderator: true)
+ end
+
+ def admins
+ @admins ||= User.where(admin: true)
+ end
+
+ def stats
+ @stats ||= {
+ topic_count: Topic.listable_topics.count,
+ post_count: Post.count,
+ user_count: User.count,
+ topics_7_days: Topic.listable_topics.where('created_at > ?', 7.days.ago).count,
+ posts_7_days: Post.where('created_at > ?', 7.days.ago).count,
+ users_7_days: User.where('created_at > ?', 7.days.ago).count
+ }
+ end
+
+end
diff --git a/app/serializers/about_serializer.rb b/app/serializers/about_serializer.rb
new file mode 100644
index 00000000000..67a04e9879d
--- /dev/null
+++ b/app/serializers/about_serializer.rb
@@ -0,0 +1,6 @@
+class AboutSerializer < ApplicationSerializer
+ has_many :moderators, serializer: BasicUserSerializer, embed: :objects
+ has_many :admins, serializer: BasicUserSerializer, embed: :objects
+
+ attributes :stats
+end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 81ac9cb725d..6d2234b07a9 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -144,6 +144,16 @@ en:
suggested_topics:
title: "Suggested Topics"
+ about:
+ title: "About"
+ stats: "Site Statistics"
+ topic_count: "Topic Count"
+ topics_7_days: "Topic Count (last 7 days)"
+ post_count: "Post Count"
+ posts_7_days: "Post Count (last 7 days)"
+ user_count: "User Count"
+ users_7_days: "User Count (last 7 days)"
+
bookmarks:
not_logged_in: "sorry, you must be logged in to bookmark posts"
created: "you've bookmarked this post"
diff --git a/config/routes.rb b/config/routes.rb
index 771cf52570b..89782fe4ca0 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -22,6 +22,8 @@ Discourse::Application.routes.draw do
mount Logster::Web => "/logs", constraints: AdminConstraint.new
end
+ resources :about
+
get "site" => "site#index"
resources :forums