Просмотр исходного кода

On unlogged admin request, always redirect to login.

Rafał Pitoń 11 лет назад
Родитель
Сommit
4fd373df12

+ 5 - 1
misago/admin/middleware.py

@@ -1,4 +1,5 @@
 from django.conf import settings
+from django.shortcuts import redirect
 from misago.admin.auth import is_admin_session, update_admin_session
 from misago.admin.views import get_protected_namespace
 from misago.admin.views.auth import login
@@ -10,6 +11,9 @@ class AdminAuthMiddleware(object):
 
         if request.admin_namespace:
             if not is_admin_session(request):
-                return login(request)
+                if request.resolver_match.url_name == 'index':
+                    return login(request)
+                else:
+                    return redirect('%s:index' % request.admin_namespace)
             else:
                 update_admin_session(request)

+ 10 - 7
misago/admin/views/errorpages.py

@@ -1,4 +1,4 @@
-from django.shortcuts import render
+from django.shortcuts import redirect, render
 from misago.admin.auth import is_admin_session, update_admin_session
 from misago.admin.views import get_protected_namespace, protected_admin_view
 
@@ -6,13 +6,16 @@ from misago.admin.views import get_protected_namespace, protected_admin_view
 # Magic error page used by admin
 @protected_admin_view
 def _error_page(request, code, message=None):
-    template_pattern = 'misago/admin/errorpages/%s.html' % code
+    if is_admin_session(request):
+        template_pattern = 'misago/admin/errorpages/%s.html' % code
 
-    response = render(request,
-                      template_pattern,
-                      {'message': message})
-    response.status_code = code
-    return response
+        response = render(request,
+                          template_pattern,
+                          {'message': message})
+        response.status_code = code
+        return response
+    else:
+        return redirect('misago:admin:index')
 
 
 def admin_error_page(f):

+ 5 - 4
misago/static/misago/admin/css/misago/dropdowns.less

@@ -33,7 +33,6 @@
 
       color: @dropdown-link-color;
       text-align: left;
-      white-space: nowrap;
 
       &:hover {
         background-color: @dropdown-link-hover-bg;
@@ -97,8 +96,6 @@
 /* Big displays */
 @media (min-width: @screen-sm-min) {
   .dropdown-menu {
-    min-width: 300px;
-
     .dropdown-title {
       background-color: #ecf0f1;
       border-radius: @border-radius-base @border-radius-base 0px 0px;
@@ -117,14 +114,18 @@
         margin-left: @line-height-computed / 2;
       }
 
+      a {
+        white-space: nowrap;
+      }
+
       button {
         background: none;
         border: none;
         padding: 3px 20px;
-        width: 100%;
 
         color: @dropdown-link-color;
         text-align: left;
+        white-space: nowrap;
 
         &:hover {
           background-color: @dropdown-link-hover-bg;

+ 0 - 8
misago/static/misago/admin/css/misago/footer.less

@@ -49,14 +49,6 @@
       }
     }
 
-    .subscript {
-      display: inline-block;
-      position: relative;
-      bottom: (@misago-branding-size  - (@misago-branding-size * 0.6)) / 2 - 1px;
-
-      font-size: @misago-branding-size * 0.6;
-    }
-
     &, &:link, &:visited {
       .opacity(0.4);
     }

+ 33 - 17
misago/static/misago/admin/css/misago/header.less

@@ -7,32 +7,48 @@
 //
 //##
 .page-header {
-	border-bottom-width: 1px;
+  border-bottom-width: 1px;
   margin: 0px;
+  margin-bottom: @line-height-computed;
   padding: @line-height-computed 0px;
 
   h1 {
-  	margin: 0px;
-  	padding: 0px;
-  	overflow: visible;
+    margin: 0px;
+    padding: 0px;
+    overflow: visible;
 
-  	font-size: @font-size-large * 1.5;
+    font-size: @font-size-large * 1.5;
 
-  	.main, .sub {
-  		float: left;
-  	}
+    .main, .sub {
+      float: left;
+    }
 
-  	.main {
-  		a {
-  			color: @text-color;
-  		}
-  	}
+    .main {
+      a {
+        color: @text-color;
+      }
+    }
 
-  	.sub {
-  		margin-left: @line-height-computed / 2;
+    .sub {
+      margin-left: @line-height-computed / 2;
 
-  		color: lighten(@text-color, 25%);
-  	}
+      color: lighten(@text-color, 25%);
+    }
+  }
+
+  .page-actions {
+    float: right;
+    margin: -4px 0px;
+
+    .dropdown-menu {
+      left: auto;
+      right: 0px;
+
+      &:after {
+        left: auto;
+        right: 12px;
+      }
+    }
   }
 }
 

+ 0 - 7
misago/static/misago/admin/css/misago/jumbotron.less

@@ -1,7 +0,0 @@
-//
-// Forum Jumbotron
-// --------------------------------------------------
-
-.jumbotron {
-  margin-top: @line-height-computed * -1;
-}

+ 7 - 0
misago/static/misago/admin/css/misago/login.less

@@ -30,6 +30,13 @@
 
     .form-body {
       border: none;
+
+      .alert {
+      	border: none;
+      	border-radius: @border-radius-base;
+      	margin-bottom: @line-height-computed;
+      	padding: @padding-base-vertical @padding-base-horizontal;
+      }
     }
   }
 }

+ 4 - 1
misago/static/misago/admin/css/misago/misago.less

@@ -7,10 +7,13 @@ html, body {
 @import "alerts.less";
 @import "buttons.less";
 @import "dropdowns.less";
+@import "modals.less";
+@import "sidenav.less";
+@import "pager.less";
+@import "tables.less";
 
 // Layout elements
 @import "navbar.less";
-@import "jumbotron.less";
 @import "header.less";
 @import "footer.less";
 

+ 23 - 0
misago/static/misago/admin/css/misago/modals.less

@@ -0,0 +1,23 @@
+//
+// Admin Modals
+// --------------------------------------------------
+
+
+.modal {
+  .modal-dialog {
+    border-radius: @border-radius-large;
+    box-shadow: 0px 0px 0px 6px @dropdown-shadow;
+
+    .modal-content {
+      .modal-header {
+        background-color: @body-bg;
+        border-radius: @border-radius-large @border-radius-large 0px 0px;
+      }
+
+      .modal-footer {
+        background-color: @form-panel-footer-bg;
+        border-radius: 0px 0px @border-radius-large @border-radius-large;
+      }
+    }
+  }
+}

+ 44 - 0
misago/static/misago/admin/css/misago/pager.less

@@ -0,0 +1,44 @@
+//
+// Pager
+// --------------------------------------------------
+
+.pager {
+  margin: 0px;
+  padding-bottom: 2px;
+
+  &>li {
+    &.page {
+      padding-right: @line-height-computed / 3;
+    }
+
+    a {
+      &, &:link, &:visited {
+        background-color: @btn-default-bg;
+        border-color: @btn-default-bg;
+        border-radius: @border-radius-base;
+        box-shadow: 0px 2px 0px 0px @btn-default-border;
+        padding: 6px 9px;
+
+        color: @btn-default-color;
+      }
+
+      &:hover {
+        background-color: darken(@btn-default-bg, 10%);
+        border-color: darken(@btn-default-bg, 10%);
+        box-shadow: 0px 2px 0px 0px darken(@btn-default-border, 10%);
+
+        color: @btn-default-color;
+      }
+
+      &:active, &:focus {
+        background-color: darken(@btn-default-bg, 15%);
+        border-color: darken(@btn-default-bg, 15%);
+        box-shadow: none;
+        position: relative;
+        top: 2px;
+
+        color: darken(@btn-default-color, 10%);
+      }
+    }
+  }
+}

+ 60 - 0
misago/static/misago/admin/css/misago/sidenav.less

@@ -0,0 +1,60 @@
+//
+// Sidenav
+// --------------------------------------------------
+
+.nav-side {
+  li {
+    a {
+      &, &:link, &:visited {
+        border-bottom: 1px solid @gray-lighter;
+        padding: @padding-base-vertical (@padding-base-vertical * 1.1);
+
+        color: @gray-light;
+
+        .fa, .glyphicon {
+          margin-left: -8px;
+          width: 30px;
+
+          text-align: center;
+        }
+      }
+
+      &:hover {
+        color: @text-color;
+      }
+
+      &:active {
+        color: @brand-primary;
+      }
+    }
+
+    &:last-child {
+      a {
+        border-bottom: none;
+      }
+    }
+
+    &.active {
+      a {
+        &, &:link, &:visited, &:active, &:hover {
+          background: @gray-dark;
+          border: none;
+          border-radius: @border-radius-base;
+
+          color: #fff;
+
+          &:after {
+            float: right;
+            content: '';
+            width: 0;
+            height: 0;
+            margin-top: 6px;
+            border-top: 4px solid transparent;
+            border-bottom: 4px solid transparent;
+            border-left: 4px solid #fff;
+          }
+        }
+      }
+    }
+  }
+}

+ 127 - 0
misago/static/misago/admin/css/misago/tables.less

@@ -0,0 +1,127 @@
+//
+// Tables
+// --------------------------------------------------
+
+.table-actions {
+  margin-bottom: @line-height-computed;
+  height: 36px;
+  overflow: visible;
+
+  &>.pull-left {
+    margin-right: @line-height-computed / 2;
+  }
+
+  &>.pull-right {
+    margin-left: @line-height-computed / 2;
+  }
+}
+
+.table-panel {
+  border: 1px solid @table-panel-border;
+  border-radius: @border-radius-base;
+  box-shadow: 0px 0px 0px 3px @table-panel-shadow;
+  margin-bottom: @line-height-computed;
+
+  table.table {
+    margin: 0px;
+
+    tr {
+      &.active {
+        td {
+          background-color: fadeOut(@brand-warning, 95%);
+        }
+      }
+
+      th {
+        background: @table-header-bg;
+        border: none;
+        padding: @table-condensed-cell-padding @table-cell-padding;
+
+        color: @table-header-color;
+        font-size: @font-size-small;
+
+        &:first-child {
+          border-radius: (@border-radius-base - 1) 0px 0px 0px;
+        }
+
+        &:last-child {
+          border-radius: 0px (@border-radius-base - 1) 0px 0px;
+        }
+      }
+
+      td {
+        background-color: #fff;
+        vertical-align: middle;
+
+        img {
+          border-radius: @border-radius-base;
+          max-width: 30px;
+          max-height: 30px;
+        }
+
+        &.row-action {
+          width: 1%;
+
+          &>.btn, .dropdown-toggle {
+            padding: 0px;
+            width: 30px;
+            height: 30px;
+
+            font-size: @font-size-large;
+            text-align: center;
+
+            &>span {
+              position: relative;
+              bottom: 1px;
+            }
+          }
+        }
+
+        &.row-select {
+          width: 1%;
+
+          label {
+            padding: 0px;
+            width: 24px;
+            height: 24px;
+
+            text-align: center;
+
+            input {
+              width: 12px;
+              height: 12px;
+            }
+
+            &.ninja-label {
+                border: 0;
+                clip: rect(0 0 0 0);
+                height: 1px;
+                margin: -1px;
+                overflow: hidden;
+                padding: 0;
+                position: absolute;
+                width: 1px;
+            }
+          }
+
+          a {
+            display: block;
+            width: 24px;
+            height: 24px;
+
+            span {
+              color: lighten(@gray-light, 5%);
+              font-size: 24px;
+            }
+
+            &.active {
+              span {
+                color: @brand-success;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}

+ 12 - 1
misago/static/misago/admin/css/misago/variables.less

@@ -111,7 +111,6 @@
 
 //== Page header
 @page-header-border-color:       darken(@body-bg, 9%);
-@page-pills-padding:             @padding-small-vertical @padding-small-horizontal;
 
 
 //== Breadcrumbs
@@ -187,6 +186,18 @@
 @form-panel-padding:                    @form-panel-padding-vertical @form-panel-padding-horizontal;
 
 
+//== Tables
+//
+
+@table-panel-bg:                        #fff;
+@table-panel-border:                    darken(@body-bg, 15%);
+@table-panel-shadow:                    darken(@body-bg, 5%);
+
+@table-header-color:                    @gray;
+@table-header-bg:                       darken(@body-bg, 5%);
+@table-header-border:                   darken(@body-bg, 15%);
+
+
 //== Error panel
 //
 //##

+ 213 - 14
misago/static/misago/admin/css/style.css

@@ -5998,7 +5998,6 @@ body {
   width: 100%;
   color: #5e5e5e;
   text-align: left;
-  white-space: nowrap;
 }
 .dropdown-menu li button:hover {
   background-color: #666666;
@@ -6039,9 +6038,6 @@ body {
 }
 /* Big displays */
 @media (min-width: 768px) {
-  .dropdown-menu {
-    min-width: 300px;
-  }
   .dropdown-menu .dropdown-title {
     background-color: #ecf0f1;
     border-radius: 4px 4px 0px 0px;
@@ -6056,13 +6052,16 @@ body {
   .dropdown-menu > li .badge {
     margin-left: 10px;
   }
+  .dropdown-menu > li a {
+    white-space: nowrap;
+  }
   .dropdown-menu > li button {
     background: none;
     border: none;
     padding: 3px 20px;
-    width: 100%;
     color: #5e5e5e;
     text-align: left;
+    white-space: nowrap;
   }
   .dropdown-menu > li button:hover {
     background-color: #666666;
@@ -6074,6 +6073,196 @@ body {
     color: #ffffff;
   }
 }
+.modal .modal-dialog {
+  border-radius: 6px;
+  box-shadow: 0px 0px 0px 6px rgba(51, 51, 51, 0.5);
+}
+.modal .modal-dialog .modal-content .modal-header {
+  background-color: #fafafa;
+  border-radius: 6px 6px 0px 0px;
+}
+.modal .modal-dialog .modal-content .modal-footer {
+  background-color: #f7f7f7;
+  border-radius: 0px 0px 6px 6px;
+}
+.nav-side li a,
+.nav-side li a:link,
+.nav-side li a:visited {
+  border-bottom: 1px solid #eeeeee;
+  padding: 6px 6.6px;
+  color: #999999;
+}
+.nav-side li a .fa,
+.nav-side li a:link .fa,
+.nav-side li a:visited .fa,
+.nav-side li a .glyphicon,
+.nav-side li a:link .glyphicon,
+.nav-side li a:visited .glyphicon {
+  margin-left: -8px;
+  width: 30px;
+  text-align: center;
+}
+.nav-side li a:hover {
+  color: #444444;
+}
+.nav-side li a:active {
+  color: #c0392b;
+}
+.nav-side li:last-child a {
+  border-bottom: none;
+}
+.nav-side li.active a,
+.nav-side li.active a:link,
+.nav-side li.active a:visited,
+.nav-side li.active a:active,
+.nav-side li.active a:hover {
+  background: #333333;
+  border: none;
+  border-radius: 4px;
+  color: #fff;
+}
+.nav-side li.active a:after,
+.nav-side li.active a:link:after,
+.nav-side li.active a:visited:after,
+.nav-side li.active a:active:after,
+.nav-side li.active a:hover:after {
+  float: right;
+  content: '';
+  width: 0;
+  height: 0;
+  margin-top: 6px;
+  border-top: 4px solid transparent;
+  border-bottom: 4px solid transparent;
+  border-left: 4px solid #fff;
+}
+.pager {
+  margin: 0px;
+  padding-bottom: 2px;
+}
+.pager > li.page {
+  padding-right: 6.66666667px;
+}
+.pager > li a,
+.pager > li a:link,
+.pager > li a:visited {
+  background-color: #ededed;
+  border-color: #ededed;
+  border-radius: 4px;
+  box-shadow: 0px 2px 0px 0px #d4d4d4;
+  padding: 6px 9px;
+  color: #777777;
+}
+.pager > li a:hover {
+  background-color: #d4d4d4;
+  border-color: #d4d4d4;
+  box-shadow: 0px 2px 0px 0px #bababa;
+  color: #777777;
+}
+.pager > li a:active,
+.pager > li a:focus {
+  background-color: #c7c7c7;
+  border-color: #c7c7c7;
+  box-shadow: none;
+  position: relative;
+  top: 2px;
+  color: #5e5e5e;
+}
+.table-actions {
+  margin-bottom: 20px;
+  height: 36px;
+  overflow: visible;
+}
+.table-actions > .pull-left {
+  margin-right: 10px;
+}
+.table-actions > .pull-right {
+  margin-left: 10px;
+}
+.table-panel {
+  border: 1px solid #d4d4d4;
+  border-radius: 4px;
+  box-shadow: 0px 0px 0px 3px #ededed;
+  margin-bottom: 20px;
+}
+.table-panel table.table {
+  margin: 0px;
+}
+.table-panel table.table tr.active td {
+  background-color: rgba(240, 173, 78, 0.05);
+}
+.table-panel table.table tr th {
+  background: #ededed;
+  border: none;
+  padding: 5px 8px;
+  color: #555555;
+  font-size: 12px;
+}
+.table-panel table.table tr th:first-child {
+  border-radius: 3px 0px 0px 0px;
+}
+.table-panel table.table tr th:last-child {
+  border-radius: 0px 3px 0px 0px;
+}
+.table-panel table.table tr td {
+  background-color: #fff;
+  vertical-align: middle;
+}
+.table-panel table.table tr td img {
+  border-radius: 4px;
+  max-width: 30px;
+  max-height: 30px;
+}
+.table-panel table.table tr td.row-action {
+  width: 1%;
+}
+.table-panel table.table tr td.row-action > .btn,
+.table-panel table.table tr td.row-action .dropdown-toggle {
+  padding: 0px;
+  width: 30px;
+  height: 30px;
+  font-size: 18px;
+  text-align: center;
+}
+.table-panel table.table tr td.row-action > .btn > span,
+.table-panel table.table tr td.row-action .dropdown-toggle > span {
+  position: relative;
+  bottom: 1px;
+}
+.table-panel table.table tr td.row-select {
+  width: 1%;
+}
+.table-panel table.table tr td.row-select label {
+  padding: 0px;
+  width: 24px;
+  height: 24px;
+  text-align: center;
+}
+.table-panel table.table tr td.row-select label input {
+  width: 12px;
+  height: 12px;
+}
+.table-panel table.table tr td.row-select label.ninja-label {
+  border: 0;
+  clip: rect(0 0 0 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px;
+}
+.table-panel table.table tr td.row-select a {
+  display: block;
+  width: 24px;
+  height: 24px;
+}
+.table-panel table.table tr td.row-select a span {
+  color: #a6a6a6;
+  font-size: 24px;
+}
+.table-panel table.table tr td.row-select a.active span {
+  color: #2ecc71;
+}
 .navbars-container {
   border-bottom: 3px solid #c7c7c7;
 }
@@ -6154,12 +6343,10 @@ body {
     margin-bottom: -3px;
   }
 }
-.jumbotron {
-  margin-top: -20px;
-}
 .page-header {
   border-bottom-width: 1px;
   margin: 0px;
+  margin-bottom: 20px;
   padding: 20px 0px;
 }
 .page-header h1 {
@@ -6179,6 +6366,18 @@ body {
   margin-left: 10px;
   color: #848484;
 }
+.page-header .page-actions {
+  float: right;
+  margin: -4px 0px;
+}
+.page-header .page-actions .dropdown-menu {
+  left: auto;
+  right: 0px;
+}
+.page-header .page-actions .dropdown-menu:after {
+  left: auto;
+  right: 12px;
+}
 .admin-footer {
   margin-top: 30px;
   margin-bottom: 30px;
@@ -6213,12 +6412,6 @@ body {
   font-size: 34.56px;
   font-weight: bold;
 }
-.misago-branding a .subscript {
-  display: inline-block;
-  position: relative;
-  bottom: 4.76px;
-  font-size: 17.28px;
-}
 .misago-branding a,
 .misago-branding a:link,
 .misago-branding a:visited {
@@ -6390,6 +6583,12 @@ body {
 .login-form .form-panel .form-body {
   border: none;
 }
+.login-form .form-panel .form-body .alert {
+  border: none;
+  border-radius: 4px;
+  margin-bottom: 20px;
+  padding: 6px 12px;
+}
 /* Big displays */
 @media (min-width: 768px) {
   .login-form {

+ 1 - 1
misago/static/misago/admin/css/style.less

@@ -3,7 +3,7 @@
 // --------------------------------------------------
 
 
-// Import Bootstrap, Misago and Flavor variables
+// Import Bootstrap and Misago variables
 // This saves us need for maintaing single large variables.less
 @import "bootstrap/variables.less";
 @import "misago/variables.less";

+ 64 - 0
misago/static/misago/admin/js/misago.js

@@ -5,3 +5,67 @@ $(function() {
   $('.tooltip-left').tooltip({placement: 'left', container: 'body'});
   $('.tooltip-right').tooltip({placement: 'right', container: 'body'});
 });
+
+
+// Tables
+function tableMassActions(label_none, label_selected) {
+  var $controller = $('.mass-controller');
+
+  function enableController(selected_no) {
+      $controller.removeClass('btn-default');
+      $controller.addClass('btn-primary');
+
+      var fin_label = label_selected.replace(0, selected_no)
+      $controller.html('<span class="fa fa-gears"></span> ' + fin_label);
+      $controller.prop("disabled", false);
+  }
+
+  function disableController() {
+      $controller.removeClass('btn-primary');
+      $controller.addClass('btn-default');
+      $controller.html('<span class="fa fa-exclamation-circle"></span> ' + label_none);
+      $controller.prop("disabled", true);
+  }
+
+  $('.table tr').each(function() {
+    var $row = $(this);
+    var $checkbox = $row.find('input[type=checkbox]');
+    var $label = $checkbox.parent();
+
+    $label.addClass('ninja-label');
+    $label.parent().append('<a href="#"><span class="fa fa-check"></span></a>');
+    var $check = $label.parent().find('a');
+
+    if ($checkbox.prop("checked")) {
+      $check.toggleClass('active');
+      $row.addClass('active');
+    }
+
+    $check.click(function() {
+      $(this).toggleClass('active');
+      if ($(this).hasClass('active')) {
+        $(this).parent().find('input').prop("checked", true);
+        $row.addClass('active');
+      } else {
+        $(this).parent().find('input').prop("checked", false);
+        $row.removeClass('active');
+      }
+
+      var selected_no = $('.table tr.active').length
+      if (selected_no > 0) {
+        enableController(selected_no);
+      } else {
+        disableController();
+      }
+      return false;
+    });
+
+    var selected_no = $('.table tr.active').length
+    if (selected_no > 0) {
+      enableController(selected_no);
+    } else {
+      $controller.html('<span class="fa fa-exclamation-circle"></span> ' + label_none);
+      $controller.prop("disabled", true);
+    }
+  });
+}

+ 4 - 0
misago/static/misago/css/misago/header.less

@@ -8,6 +8,10 @@
 //##
 .page-header {
   margin-top: @line-height-computed * -1;
+
+  h1 {
+    font-size: @font-size-base * 2.3;
+  }
 }
 
 

+ 1 - 0
misago/static/misago/css/misago/misago.less

@@ -3,6 +3,7 @@
 @import "buttons.less";
 @import "dropdowns.less";
 @import "navs.less";
+@import "modals.less";
 
 // Layout elements
 @import "navbar.less";

+ 27 - 0
misago/static/misago/css/misago/modals.less

@@ -0,0 +1,27 @@
+//
+// Modals
+// --------------------------------------------------
+
+
+.modal {
+  .modal-dialog {
+    border-radius: @border-radius-large;
+    box-shadow: 0px 0px 0px 6px @dropdown-shadow;
+
+    .modal-content {
+      .modal-header {
+        background: @modal-header-bg-color;
+        border-radius: @border-radius-large @border-radius-large 0px 0px;
+
+        .modal-title {
+          color: @modal-title-color;
+        }
+      }
+
+      .modal-footer {
+        background: @modal-footer-bg-color;
+        border-radius: 0px 0px @border-radius-large @border-radius-large;
+      }
+    }
+  }
+}

+ 77 - 0
misago/static/misago/css/misago/navs.less

@@ -82,6 +82,54 @@
 }
 
 
+/* Sidenav */
+.nav-side {
+  li {
+    a {
+      &, &:link, &:visited {
+        border-bottom: 1px solid @nav-side-border;
+        padding: @nav-side-padding;
+
+        color: @nav-side-color;
+
+        .fa, .glyphicon {
+          margin-left: -8px;
+          width: 30px;
+
+          text-align: center;
+        }
+      }
+
+      &:hover {
+        color: @nav-side-hover-color;
+      }
+
+      &:active {
+        color: @nav-side-active-color;
+      }
+    }
+
+    &:last-child {
+      a {
+        border-bottom: none;
+      }
+    }
+
+    &.active {
+      a {
+        &, &:link, &:visited, &:active, &:hover {
+          background: @nav-side-active-bg;
+          border: none;
+          border-radius: @border-radius-base;
+
+          color: @nav-side-active-text-color;
+        }
+      }
+    }
+  }
+}
+
+
 /* Badges */
 .nav-pills, .nav-tabs {
   &>li {
@@ -95,6 +143,35 @@
   }
 }
 
+.nav-side {
+  li {
+    a {
+      &, &:link, &:visited {
+        .badge {
+          background: transparent;
+          float: right;
+          margin-top: 1px;
+
+          color: @text-color;
+        }
+      }
+    }
+
+    &.active {
+      a {
+        &, &:link, &:visited, &:active, &:hover {
+          .badge {
+            background: @nav-side-active-text-color;
+
+            color: @nav-side-active-bg;
+          }
+        }
+      }
+    }
+  }
+}
+
+
 /* Label */
 .nav-pills, .nav-tabs {
   &>li {

+ 35 - 8
misago/static/misago/css/misago/variables.less

@@ -140,9 +140,19 @@
 @nav-pills-active-link-hover-bg:            #666;
 @nav-pills-active-link-hover-color:         #fff;
 
+//==Sidenav
+@nav-side-border:                           @gray-lighter;
+@nav-side-padding:                          6px 10px;
+
+@nav-side-color:                            @gray-light;
+@nav-side-hover-color:                      @text-color;
+@nav-side-active-color:                     @brand-primary;
+
+@nav-side-active-bg:                        @gray-dark;
+@nav-side-active-text-color:                #fff;
+
 //== Page header
 @page-header-border-color:       darken(@body-bg, 9%);
-@page-pills-padding:             @padding-small-vertical @padding-small-horizontal;
 
 
 //== Breadcrumbs
@@ -225,13 +235,6 @@
 @error-panel-border:               darken(@body-bg, 15%);
 @error-panel-shadow:               darken(@body-bg, 5%);
 
-//== Miscellaneous
-//
-//##
-
-//** Horizontal line color.
-@hr-border:                   darken(@body-bg, 10%);
-
 
 //== Alerts
 //
@@ -251,3 +254,27 @@
 
 @alert-danger-bg:             #c0392b;
 @alert-danger-text:           #fff;
+
+
+//== Modals
+//
+//##
+
+@modal-title-color:                  @gray;
+
+@modal-header-bg-color:              darken(@body-bg, 1%);
+@modal-header-border-color:          darken(@modal-header-bg-color, 5%);
+
+@modal-footer-bg-color:              darken(@body-bg, 2%);
+@modal-footer-border-color:          darken(@modal-footer-bg-color, 5%);
+
+
+//== Miscellaneous
+//
+//##
+
+//** Horizontal line color.
+@hr-border:                   darken(@body-bg, 10%);
+
+//** Badge radius
+@badge-border-radius:         @border-radius-small;