Browse Source

Brought back admin and email templates

Rafał Pitoń 10 years ago
parent
commit
d7bd8c1588
97 changed files with 3636 additions and 352 deletions
  1. 0 0
      misago/static/misago/css/_misago/alerts.less
  2. 0 0
      misago/static/misago/css/_misago/buttons.less
  3. 0 0
      misago/static/misago/css/_misago/datepicker.less
  4. 0 0
      misago/static/misago/css/_misago/dropdowns.less
  5. 0 0
      misago/static/misago/css/_misago/editor.less
  6. 0 0
      misago/static/misago/css/_misago/errorpages.less
  7. 0 0
      misago/static/misago/css/_misago/events.less
  8. 0 0
      misago/static/misago/css/_misago/forms.less
  9. 0 0
      misago/static/misago/css/_misago/forums.less
  10. 0 0
      misago/static/misago/css/_misago/header.less
  11. 0 0
      misago/static/misago/css/_misago/index.less
  12. 0 0
      misago/static/misago/css/_misago/inputs.less
  13. 0 0
      misago/static/misago/css/_misago/jumbotron.less
  14. 0 0
      misago/static/misago/css/_misago/loader.less
  15. 0 0
      misago/static/misago/css/_misago/markup.less
  16. 0 0
      misago/static/misago/css/_misago/misago.less
  17. 0 0
      misago/static/misago/css/_misago/modals.less
  18. 0 0
      misago/static/misago/css/_misago/navbar.less
  19. 0 0
      misago/static/misago/css/_misago/navs.less
  20. 0 0
      misago/static/misago/css/_misago/notifications.less
  21. 0 0
      misago/static/misago/css/_misago/pager.less
  22. 0 0
      misago/static/misago/css/_misago/panels.less
  23. 0 0
      misago/static/misago/css/_misago/participants.less
  24. 0 0
      misago/static/misago/css/_misago/posting.less
  25. 0 0
      misago/static/misago/css/_misago/posts.less
  26. 0 0
      misago/static/misago/css/_misago/profile.less
  27. 0 0
      misago/static/misago/css/_misago/progressbars.less
  28. 0 0
      misago/static/misago/css/_misago/signin.less
  29. 0 0
      misago/static/misago/css/_misago/states.less
  30. 0 0
      misago/static/misago/css/_misago/tables.less
  31. 0 0
      misago/static/misago/css/_misago/threadmap.less
  32. 0 0
      misago/static/misago/css/_misago/threadslists.less
  33. 0 0
      misago/static/misago/css/_misago/typography.less
  34. 0 0
      misago/static/misago/css/_misago/usercp.less
  35. 0 0
      misago/static/misago/css/_misago/userslists.less
  36. 391 0
      misago/static/misago/css/_misago/variables.less
  37. 0 0
      misago/static/misago/css/_misago/warnings.less
  38. 0 0
      misago/static/misago/css/_misago/yesnoswitch.less
  39. 47 351
      misago/static/misago/css/misago/variables.less
  40. BIN
      misago/static/misago/img/misago_logo.png
  41. 76 0
      misago/templates/misago/admin/bans/form.html
  42. 117 0
      misago/templates/misago/admin/bans/list.html
  43. 25 0
      misago/templates/misago/admin/base.html
  44. 26 0
      misago/templates/misago/admin/base_thin.html
  45. 70 0
      misago/templates/misago/admin/conf/group.html
  46. 57 0
      misago/templates/misago/admin/conf/index.html
  47. 27 0
      misago/templates/misago/admin/errorpages/403.html
  48. 23 0
      misago/templates/misago/admin/errorpages/404.html
  49. 28 0
      misago/templates/misago/admin/errorpages/csrf_failure.html
  50. 24 0
      misago/templates/misago/admin/errorpages/csrf_failure_authenticated.html
  51. 59 0
      misago/templates/misago/admin/forumroles/form.html
  52. 69 0
      misago/templates/misago/admin/forumroles/forumroles.html
  53. 58 0
      misago/templates/misago/admin/forumroles/list.html
  54. 79 0
      misago/templates/misago/admin/forumroles/roleforums.html
  55. 45 0
      misago/templates/misago/admin/forums/delete.html
  56. 80 0
      misago/templates/misago/admin/forums/form.html
  57. 89 0
      misago/templates/misago/admin/forums/list.html
  58. 26 0
      misago/templates/misago/admin/generic/base.html
  59. 65 0
      misago/templates/misago/admin/generic/form.html
  60. 189 0
      misago/templates/misago/admin/generic/list.html
  61. 37 0
      misago/templates/misago/admin/generic/paginator.html
  62. 133 0
      misago/templates/misago/admin/index.html
  63. 62 0
      misago/templates/misago/admin/labels/form.html
  64. 70 0
      misago/templates/misago/admin/labels/list.html
  65. 78 0
      misago/templates/misago/admin/login.html
  66. 43 0
      misago/templates/misago/admin/logout.html
  67. 24 0
      misago/templates/misago/admin/messages.html
  68. 45 0
      misago/templates/misago/admin/navbar.html
  69. 36 0
      misago/templates/misago/admin/permissions_table.html
  70. 71 0
      misago/templates/misago/admin/ranks/form.html
  71. 133 0
      misago/templates/misago/admin/ranks/list.html
  72. 59 0
      misago/templates/misago/admin/roles/form.html
  73. 74 0
      misago/templates/misago/admin/roles/list.html
  74. 90 0
      misago/templates/misago/admin/users/ban.html
  75. 157 0
      misago/templates/misago/admin/users/delete.html
  76. 93 0
      misago/templates/misago/admin/users/edit.html
  77. 124 0
      misago/templates/misago/admin/users/list.html
  78. 66 0
      misago/templates/misago/admin/users/new.html
  79. 63 0
      misago/templates/misago/admin/warnings/form.html
  80. 134 0
      misago/templates/misago/admin/warnings/list.html
  81. 18 0
      misago/templates/misago/emails/activation/by_admin.html
  82. 14 0
      misago/templates/misago/emails/activation/by_admin.txt
  83. 13 0
      misago/templates/misago/emails/activation/by_user.html
  84. 10 0
      misago/templates/misago/emails/activation/by_user.txt
  85. 90 0
      misago/templates/misago/emails/base.html
  86. 11 0
      misago/templates/misago/emails/base.txt
  87. 18 0
      misago/templates/misago/emails/change_email_password.html
  88. 14 0
      misago/templates/misago/emails/change_email_password.txt
  89. 18 0
      misago/templates/misago/emails/change_password_form_link.html
  90. 14 0
      misago/templates/misago/emails/change_password_form_link.txt
  91. 21 0
      misago/templates/misago/emails/privatethread/added.html
  92. 14 0
      misago/templates/misago/emails/privatethread/added.txt
  93. 25 0
      misago/templates/misago/emails/register/complete.html
  94. 18 0
      misago/templates/misago/emails/register/complete.txt
  95. 38 0
      misago/templates/misago/emails/register/inactive.html
  96. 35 0
      misago/templates/misago/emails/register/inactive.txt
  97. 3 1
      misago/templates/misago/index.html

+ 0 - 0
misago/static/misago/css/misago/alerts.less → misago/static/misago/css/_misago/alerts.less


+ 0 - 0
misago/static/misago/css/misago/buttons.less → misago/static/misago/css/_misago/buttons.less


+ 0 - 0
misago/static/misago/css/misago/datepicker.less → misago/static/misago/css/_misago/datepicker.less


+ 0 - 0
misago/static/misago/css/misago/dropdowns.less → misago/static/misago/css/_misago/dropdowns.less


+ 0 - 0
misago/static/misago/css/misago/editor.less → misago/static/misago/css/_misago/editor.less


+ 0 - 0
misago/static/misago/css/misago/errorpages.less → misago/static/misago/css/_misago/errorpages.less


+ 0 - 0
misago/static/misago/css/misago/events.less → misago/static/misago/css/_misago/events.less


+ 0 - 0
misago/static/misago/css/misago/forms.less → misago/static/misago/css/_misago/forms.less


+ 0 - 0
misago/static/misago/css/misago/forums.less → misago/static/misago/css/_misago/forums.less


+ 0 - 0
misago/static/misago/css/misago/header.less → misago/static/misago/css/_misago/header.less


+ 0 - 0
misago/static/misago/css/misago/index.less → misago/static/misago/css/_misago/index.less


+ 0 - 0
misago/static/misago/css/misago/inputs.less → misago/static/misago/css/_misago/inputs.less


+ 0 - 0
misago/static/misago/css/misago/jumbotron.less → misago/static/misago/css/_misago/jumbotron.less


+ 0 - 0
misago/static/misago/css/misago/loader.less → misago/static/misago/css/_misago/loader.less


+ 0 - 0
misago/static/misago/css/misago/markup.less → misago/static/misago/css/_misago/markup.less


+ 0 - 0
misago/static/misago/css/misago/misago.less → misago/static/misago/css/_misago/misago.less


+ 0 - 0
misago/static/misago/css/misago/modals.less → misago/static/misago/css/_misago/modals.less


+ 0 - 0
misago/static/misago/css/misago/navbar.less → misago/static/misago/css/_misago/navbar.less


+ 0 - 0
misago/static/misago/css/misago/navs.less → misago/static/misago/css/_misago/navs.less


+ 0 - 0
misago/static/misago/css/misago/notifications.less → misago/static/misago/css/_misago/notifications.less


+ 0 - 0
misago/static/misago/css/misago/pager.less → misago/static/misago/css/_misago/pager.less


+ 0 - 0
misago/static/misago/css/misago/panels.less → misago/static/misago/css/_misago/panels.less


+ 0 - 0
misago/static/misago/css/misago/participants.less → misago/static/misago/css/_misago/participants.less


+ 0 - 0
misago/static/misago/css/misago/posting.less → misago/static/misago/css/_misago/posting.less


+ 0 - 0
misago/static/misago/css/misago/posts.less → misago/static/misago/css/_misago/posts.less


+ 0 - 0
misago/static/misago/css/misago/profile.less → misago/static/misago/css/_misago/profile.less


+ 0 - 0
misago/static/misago/css/misago/progressbars.less → misago/static/misago/css/_misago/progressbars.less


+ 0 - 0
misago/static/misago/css/misago/signin.less → misago/static/misago/css/_misago/signin.less


+ 0 - 0
misago/static/misago/css/misago/states.less → misago/static/misago/css/_misago/states.less


+ 0 - 0
misago/static/misago/css/misago/tables.less → misago/static/misago/css/_misago/tables.less


+ 0 - 0
misago/static/misago/css/misago/threadmap.less → misago/static/misago/css/_misago/threadmap.less


+ 0 - 0
misago/static/misago/css/misago/threadslists.less → misago/static/misago/css/_misago/threadslists.less


+ 0 - 0
misago/static/misago/css/misago/typography.less → misago/static/misago/css/_misago/typography.less


+ 0 - 0
misago/static/misago/css/misago/usercp.less → misago/static/misago/css/_misago/usercp.less


+ 0 - 0
misago/static/misago/css/misago/userslists.less → misago/static/misago/css/_misago/userslists.less


+ 391 - 0
misago/static/misago/css/_misago/variables.less

@@ -0,0 +1,391 @@
+//
+// Misago Variables
+// --------------------------------------------------
+
+
+//== Colors
+//
+//## Basic colors for use in this flavor
+
+@brand-primary:         #3498db;
+@brand-accent:          #e74c3c;
+@brand-success:         #2ecc71;
+@brand-info:            #5bc0de;
+@brand-warning:         #f0ad4e;
+@brand-danger:          #e74c3c;
+
+@brand-follow:          #EB5BCC;
+@brand-block:           @brand-danger;
+
+
+// Background color for `<body>`.
+@body-bg:               #fff;
+
+// Global text color on `<body>`.
+@text-color:            #333;
+
+// Global state colors
+@state-default:         @gray-light;
+@state-hover:           @text-color;
+@state-clicked:         @brand-primary;
+@state-active:          @brand-accent;
+
+@state-online:                #2ecc71;
+@state-offline:               #95a5a6;
+@state-banned:                #e74c3c;
+
+
+// Headings color
+@headings-small-color:  darken(@body-bg, 30%);
+
+// Global textual link color.
+@link-color:            @brand-primary;
+@link-hover-color:      darken(@link-color, 15%);
+
+// Text muted color
+@text-muted:            darken(@body-bg, 40%);
+
+@link-muted-color:            @gray-darker;
+
+// Components
+@component-active-bg:         @state-active;
+@component-active-color:      #fff;
+
+@loader-color:                @brand-accent;
+@loader-text-color:           @text-muted;
+
+//== Navbar
+//
+//## Navbar style
+
+@navbar-default-bg:                lighten(#ecf0f1, 3%);
+@navbar-default-border:            #ecf0f1;
+
+
+// Navbar brand
+@navbar-brand-size:                        @font-size-large * 1.6;
+
+@navbar-default-brand-color:               #555;
+@navbar-default-brand-hover-color:         #555;
+
+
+// Navbar icon-based menu
+@navbar-icon-size:                      @navbar-height / 2.5;
+@navbar-icon-link-bg:                   transparent;
+@navbar-icon-link-border:               transparent;
+@navbar-icon-link-color:                @state-default;
+
+@navbar-icon-link-hover-bg:             darken(@navbar-default-border, 2%);
+@navbar-icon-link-hover-border:         darken(@navbar-default-border, 2%);
+@navbar-icon-link-hover-color:          @state-hover;
+
+@navbar-icon-link-active-bg:            darken(@navbar-default-border, 2%);
+@navbar-icon-link-active-border:        darken(@navbar-default-border, 2%);
+@navbar-icon-link-active-color:         @state-clicked;
+
+@navbar-icon-link-open-bg:              @state-active;
+@navbar-icon-link-open-border:          @state-active;
+@navbar-icon-link-open-color:           #fff;
+
+
+// Only User dropdown switch uses those colors
+@navbar-user-name-color:                @gray;
+@navbar-user-name-hover-color:          @navbar-user-name-color;
+@navbar-user-name-active-color:         @state-clicked;
+
+@navbar-user-caret-color:              @state-default;
+@navbar-user-caret-hover-color:        @state-hover;
+@navbar-user-caret-active-color:       @state-clicked;
+
+
+// Guest Sign in button
+@btn-sign-in-color:                    @brand-primary;
+@btn-sign-in-bg:                       @navbar-default-bg;
+@btn-sign-in-border:                   transparent;
+
+@btn-sign-in-hover-color:              @brand-primary;
+@btn-sign-in-hover-bg:                 fadeOut(@brand-primary, 90%);
+@btn-sign-in-hover-border:             transparent;
+
+@btn-sign-in-active-color:             #fff;
+@btn-sign-in-active-bg:                @brand-primary;
+@btn-sign-in-active-border:            @brand-primary;
+
+
+// Guest Register button
+@btn-register-color:                   fadeOut(@brand-accent, 30%);
+@btn-register-bg:                      @navbar-default-bg;
+@btn-register-border:                  fadeOut(@brand-accent, 70%);
+
+@btn-register-hover-color:             @brand-accent;
+@btn-register-hover-bg:                fadeOut(@brand-accent, 90%);
+@btn-register-hover-border:            transparent;
+
+@btn-register-active-color:            #fff;
+@btn-register-active-bg:               @brand-accent;
+@btn-register-active-border:           @brand-accent;
+
+
+//== Dropdowns
+//
+//## Misago dropdowns flavor
+
+// Dropdown title
+@dropdown-title-color:           @text-color;
+@dropdown-title-bg:              @navbar-default-bg;
+@dropdown-title-border:          darken(@navbar-default-border, 5%);
+
+// Dropdown link text color.
+@dropdown-link-color:            @text-color;
+
+@dropdown-link-hover-color:      #fff;
+@dropdown-link-hover-bg:         lighten(@state-hover, 15%);
+
+@dropdown-link-active-color:     #fff;
+@dropdown-link-active-bg:        @state-clicked;
+
+// Open dropdown shadow color.
+@dropdown-shadow:                fadeOut(#333, 50%);
+
+
+//== Navs
+//
+//##
+
+//=== Shared nav styles
+@nav-link-hover-bg:                         transparent;
+
+@nav-link-color:                            @gray-light;
+@nav-link-hover-color:                      @text-color;
+
+//== Tabs
+@nav-tabs-padding:                          10px 12px;
+@nav-tabs-border-color:                     #ddd;
+
+@nav-tabs-link-hover-border-color:          darken(@nav-tabs-border-color, 40%);
+@nav-tabs-link-active-border-color:         @state-active;
+
+@nav-tabs-link-clicked-bg:                  transparent;
+@nav-tabs-link-clicked-color:               @state-clicked;
+@nav-tabs-link-clicked-border-color:        @state-clicked;
+
+@nav-tabs-active-link-bg:                   transparent;
+@nav-tabs-active-link-color:                @state-hover;
+@nav-tabs-active-link-border-color:         @state-active;
+
+@nav-tabs-justified-link-border-color:            #ddd;
+@nav-tabs-justified-active-link-border-color:     @body-bg;
+
+//== Pills
+@nav-pills-padding:                         6px 7px;
+@nav-pills-border-radius:                   @border-radius-base;
+@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%);
+
+
+//== Breadcrumbs
+//
+//##
+
+@breadcrumb-padding-vertical:   8px;
+@breadcrumb-padding-horizontal: 0px;
+
+@breadcrumb-bg:                 transparent;
+@breadcrumb-color:              darken(@body-bg, 40%);
+@breadcrumb-active-color:       @text-color;
+
+
+//== Page footer
+//
+//## Footer appearance
+
+@footer-color:                   darken(@body-bg, 35%);
+
+// Size of Misago's branding in footer
+@misago-branding-size:           @font-size-large * 1.6;
+
+// Footer links
+@footer-link-color:              @state-default;
+@footer-link-hover-color:        @state-hover;
+@footer-link-active-color:       @state-clicked;
+
+
+//== Buttons
+//
+//## For each of Bootstrap's buttons, define text, background and border color.
+
+@btn-font-weight:                normal;
+
+
+@btn-default-color:              #777;
+@btn-default-bg:                 darken(@body-bg, 5%);
+@btn-default-border:             darken(@btn-default-bg, 10%);
+
+@btn-default-hover-color:        @text-color;
+@btn-default-hover-bg:           darken(@body-bg, 2%);
+@btn-default-hover-border:       #999;
+
+@btn-default-active-color:       @text-color;
+@btn-default-active-bg:          darken(@body-bg, 6%);
+@btn-default-active-border:      #999;
+
+@btn-primary-color:              #fff;
+@btn-primary-bg:                 @brand-primary;
+@btn-primary-border:             darken(@btn-primary-bg, 15%);
+
+@btn-success-color:              #fff;
+@btn-success-bg:                 @brand-success;
+@btn-success-border:             darken(@btn-success-bg, 15%);
+
+@btn-warning-color:              #fff;
+@btn-warning-bg:                 @brand-warning;
+@btn-warning-border:             darken(@btn-warning-bg, 15%);
+
+@btn-danger-color:               #fff;
+@btn-danger-bg:                  @brand-danger;
+@btn-danger-border:              darken(@btn-danger-bg, 15%);
+
+
+//== Forms
+//
+@legend-color:                          darken(@body-bg, 40%);
+@field-help-block-color:                darken(@body-bg, 50%);
+
+//## Misago wraps forms into panels
+@form-panel-bg:                         #fff;
+@form-panel-border:                     darken(@body-bg, 15%);
+@form-panel-shadow:                     darken(@body-bg, 5%);
+@form-panel-footer-bg:                  darken(@body-bg, 1%);
+@form-panel-padding-vertical:           (@padding-large-vertical * 1.5);
+@form-panel-padding-horizontal:         @padding-large-horizontal;
+@form-panel-padding:                    @form-panel-padding-vertical @form-panel-padding-horizontal;
+
+//## Misago Yes-No switch
+@yesno-switch-default:                  lighten(@gray-light, 25%);
+@yesno-switch-active:                   @brand-primary;
+
+
+//== Panels
+//
+//##
+
+@panel-bg:                    #fff;
+@panel-shadow:                darken(@body-bg, 5%);
+@panel-body-padding:          15px;
+
+@panel-default-border:        darken(@body-bg, 15%);
+
+//** Border color for elements within panels
+@panel-inner-border:          darken(@body-bg, 8%);
+@panel-footer-bg:             @panel-bg;
+
+//** Table panels
+@table-panel-bg:                        @panel-bg;
+@table-panel-border:                    @panel-default-border;
+@table-panel-shadow:                    @panel-shadow;
+
+@table-row-highlight:                   fadeOut(@brand-warning, 90%);
+
+@table-header-color:                    @gray;
+@table-header-bg:                       darken(@body-bg, 5%);
+@table-header-border:                   darken(@body-bg, 15%);
+
+//** User cards
+@user-card-bg:                         @body-bg;
+@user-card-border:                     darken(@body-bg, 15%);
+@user-card-shadow:                     darken(@body-bg, 15%);
+
+@user-card-hover-border:               fadeOut(@state-hover, 50%);
+@user-card-hover-shadow:               fadeOut(@state-hover, 50%);
+
+@user-card-active-border:              @state-clicked;
+@user-card-active-shadow:              @state-clicked;
+
+//** Post panels
+@post-panel-bg:                        @panel-bg;
+@post-panel-border:                    @panel-default-border;
+
+@post-active-panel-bg:                 lighten(#3498db, 44%);
+@post-active-panel-border:             lighten(#3498db, 38%);
+
+
+//== Form states and alerts
+//
+//## Define colors for form feedback states and, by default, alerts.
+
+@state-success-text:             #27ae60;
+@state-success-text-contrast:    #fff;
+@state-success-bg:               #2ecc71;
+
+@state-info-text:                @brand-primary;
+@state-info-text-contrast:       #fff;
+@state-info-bg:                  @brand-primary;
+
+@state-warning-text:             #e67e22;
+@state-warning-text-contrast:    #fff;
+@state-warning-bg:               #e67e22;
+
+@state-danger-text:              #c0392b;
+@state-danger-text-contrast:     #fff;
+@state-danger-bg:                darken(#e74c3c, 12%);
+
+
+//== Alerts
+//
+//## Define alert colors, border radius, and padding.
+
+@alert-padding:               14px;
+@alert-border-radius:         @border-radius-large;
+
+@alert-success-bg:            @state-success-bg;
+@alert-success-text:          @state-success-text-contrast;
+
+@alert-info-bg:               @state-info-bg;
+@alert-info-text:             @state-info-text-contrast;
+
+@alert-warning-bg:            @state-warning-bg;
+@alert-warning-text:          @state-warning-text-contrast;
+
+@alert-danger-bg:             @state-danger-bg;
+@alert-danger-text:           @state-danger-text-contrast;
+
+@alert-default-bg:            @gray-lighter;
+@alert-default-text:          @gray;
+
+
+//== 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;

+ 0 - 0
misago/static/misago/css/misago/warnings.less → misago/static/misago/css/_misago/warnings.less


+ 0 - 0
misago/static/misago/css/misago/yesnoswitch.less → misago/static/misago/css/_misago/yesnoswitch.less


+ 47 - 351
misago/static/misago/css/misago/variables.less

@@ -1,391 +1,87 @@
 //
 //
-// Misago Variables
+// Misago Default Theme Variables
 // --------------------------------------------------
 // --------------------------------------------------
 
 
 
 
 //== Colors
 //== Colors
 //
 //
-//## Basic colors for use in this flavor
+//## Gray and brand colors for use across Bootstrap.
+
+@gray-base:              #000;
+@gray-darker:            lighten(@gray-base, 13.5%); // #222
+@gray-dark:              lighten(@gray-base, 20%);   // #333
+@gray:                   lighten(@gray-base, 33.5%); // #555
+@gray-light:             lighten(@gray-base, 46.7%); // #777
+@gray-lighter:           lighten(@gray-base, 93.5%); // #eee
 
 
 @brand-primary:         #3498db;
 @brand-primary:         #3498db;
-@brand-accent:          #e74c3c;
-@brand-success:         #2ecc71;
+@brand-success:         #5cb85c;
 @brand-info:            #5bc0de;
 @brand-info:            #5bc0de;
-@brand-warning:         #f0ad4e;
+@brand-warning:         #d35400;
 @brand-danger:          #e74c3c;
 @brand-danger:          #e74c3c;
 
 
-@brand-follow:          #EB5BCC;
-@brand-block:           @brand-danger;
 
 
+//== Scaffolding
+//
+//## Settings for some of the most global styles.
 
 
-// Background color for `<body>`.
+//** Background color for `<body>`.
 @body-bg:               #fff;
 @body-bg:               #fff;
+//** Global text color on `<body>`.
+@text-color:            @gray-dark;
 
 
-// Global text color on `<body>`.
-@text-color:            #333;
-
-// Global state colors
-@state-default:         @gray-light;
-@state-hover:           @text-color;
-@state-clicked:         @brand-primary;
-@state-active:          @brand-accent;
-
-@state-online:                #2ecc71;
-@state-offline:               #95a5a6;
-@state-banned:                #e74c3c;
-
-
-// Headings color
-@headings-small-color:  darken(@body-bg, 30%);
-
-// Global textual link color.
+//** Global textual link color.
 @link-color:            @brand-primary;
 @link-color:            @brand-primary;
+//** Link hover color set via `darken()` function.
 @link-hover-color:      darken(@link-color, 15%);
 @link-hover-color:      darken(@link-color, 15%);
+//** Link hover decoration.
+@link-hover-decoration: underline;
 
 
-// Text muted color
-@text-muted:            darken(@body-bg, 40%);
-
-@link-muted-color:            @gray-darker;
-
-// Components
-@component-active-bg:         @state-active;
-@component-active-color:      #fff;
+//** In-site link state default
+@state-default:         @gray-light;
+@state-hover:           @gray-dark;
+@state-clicked:         @link-color;
 
 
-@loader-color:                @brand-accent;
-@loader-text-color:           @text-muted;
 
 
 //== Navbar
 //== Navbar
 //
 //
-//## Navbar style
-
-@navbar-default-bg:                lighten(#ecf0f1, 3%);
-@navbar-default-border:            #ecf0f1;
-
-
-// Navbar brand
-@navbar-brand-size:                        @font-size-large * 1.6;
-
-@navbar-default-brand-color:               #555;
-@navbar-default-brand-hover-color:         #555;
-
-
-// Navbar icon-based menu
-@navbar-icon-size:                      @navbar-height / 2.5;
-@navbar-icon-link-bg:                   transparent;
-@navbar-icon-link-border:               transparent;
-@navbar-icon-link-color:                @state-default;
-
-@navbar-icon-link-hover-bg:             darken(@navbar-default-border, 2%);
-@navbar-icon-link-hover-border:         darken(@navbar-default-border, 2%);
-@navbar-icon-link-hover-color:          @state-hover;
-
-@navbar-icon-link-active-bg:            darken(@navbar-default-border, 2%);
-@navbar-icon-link-active-border:        darken(@navbar-default-border, 2%);
-@navbar-icon-link-active-color:         @state-clicked;
-
-@navbar-icon-link-open-bg:              @state-active;
-@navbar-icon-link-open-border:          @state-active;
-@navbar-icon-link-open-color:           #fff;
-
-
-// Only User dropdown switch uses those colors
-@navbar-user-name-color:                @gray;
-@navbar-user-name-hover-color:          @navbar-user-name-color;
-@navbar-user-name-active-color:         @state-clicked;
-
-@navbar-user-caret-color:              @state-default;
-@navbar-user-caret-hover-color:        @state-hover;
-@navbar-user-caret-active-color:       @state-clicked;
-
-
-// Guest Sign in button
-@btn-sign-in-color:                    @brand-primary;
-@btn-sign-in-bg:                       @navbar-default-bg;
-@btn-sign-in-border:                   transparent;
-
-@btn-sign-in-hover-color:              @brand-primary;
-@btn-sign-in-hover-bg:                 fadeOut(@brand-primary, 90%);
-@btn-sign-in-hover-border:             transparent;
-
-@btn-sign-in-active-color:             #fff;
-@btn-sign-in-active-bg:                @brand-primary;
-@btn-sign-in-active-border:            @brand-primary;
-
-
-// Guest Register button
-@btn-register-color:                   fadeOut(@brand-accent, 30%);
-@btn-register-bg:                      @navbar-default-bg;
-@btn-register-border:                  fadeOut(@brand-accent, 70%);
-
-@btn-register-hover-color:             @brand-accent;
-@btn-register-hover-bg:                fadeOut(@brand-accent, 90%);
-@btn-register-hover-border:            transparent;
-
-@btn-register-active-color:            #fff;
-@btn-register-active-bg:               @brand-accent;
-@btn-register-active-border:           @brand-accent;
-
-
-//== Dropdowns
-//
-//## Misago dropdowns flavor
-
-// Dropdown title
-@dropdown-title-color:           @text-color;
-@dropdown-title-bg:              @navbar-default-bg;
-@dropdown-title-border:          darken(@navbar-default-border, 5%);
-
-// Dropdown link text color.
-@dropdown-link-color:            @text-color;
-
-@dropdown-link-hover-color:      #fff;
-@dropdown-link-hover-bg:         lighten(@state-hover, 15%);
-
-@dropdown-link-active-color:     #fff;
-@dropdown-link-active-bg:        @state-clicked;
-
-// Open dropdown shadow color.
-@dropdown-shadow:                fadeOut(#333, 50%);
-
-
-//== Navs
-//
 //##
 //##
 
 
-//=== Shared nav styles
-@nav-link-hover-bg:                         transparent;
-
-@nav-link-color:                            @gray-light;
-@nav-link-hover-color:                      @text-color;
-
-//== Tabs
-@nav-tabs-padding:                          10px 12px;
-@nav-tabs-border-color:                     #ddd;
+// Basics of a navbar
+@navbar-height:                    50px;
+@navbar-margin-bottom:             @line-height-computed;
+@navbar-border-radius:             @border-radius-base;
+@navbar-padding-horizontal:        floor((@grid-gutter-width / 2));
+@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);
+@navbar-collapse-max-height:       340px;
 
 
-@nav-tabs-link-hover-border-color:          darken(@nav-tabs-border-color, 40%);
-@nav-tabs-link-active-border-color:         @state-active;
+@navbar-default-color:             #777;
+@navbar-default-bg:                @body-bg;
+@navbar-default-border:            darken(@navbar-default-bg, 6.5%);
 
 
-@nav-tabs-link-clicked-bg:                  transparent;
-@nav-tabs-link-clicked-color:               @state-clicked;
-@nav-tabs-link-clicked-border-color:        @state-clicked;
+// Navbar links
+@navbar-default-link-color:                darken(@gray-lighter, 20%);
+@navbar-default-link-hover-color:          @gray-light;
+@navbar-default-link-hover-bg:             transparent;
+@navbar-default-link-active-color:         @gray-darker;
+@navbar-default-link-active-bg:            transparent;
 
 
-@nav-tabs-active-link-bg:                   transparent;
-@nav-tabs-active-link-color:                @state-hover;
-@nav-tabs-active-link-border-color:         @state-active;
+// Navbar brand label
+@navbar-default-brand-color:               @gray-dark;
+@navbar-default-brand-hover-color:         @gray-dark;
 
 
-@nav-tabs-justified-link-border-color:            #ddd;
-@nav-tabs-justified-active-link-border-color:     @body-bg;
 
 
-//== Pills
-@nav-pills-padding:                         6px 7px;
-@nav-pills-border-radius:                   @border-radius-base;
-@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%);
-
-
-//== Breadcrumbs
+//== Site Footer
 //
 //
 //##
 //##
 
 
-@breadcrumb-padding-vertical:   8px;
-@breadcrumb-padding-horizontal: 0px;
-
-@breadcrumb-bg:                 transparent;
-@breadcrumb-color:              darken(@body-bg, 40%);
-@breadcrumb-active-color:       @text-color;
-
-
-//== Page footer
-//
-//## Footer appearance
-
 @footer-color:                   darken(@body-bg, 35%);
 @footer-color:                   darken(@body-bg, 35%);
+@footer-noscript-color:          #d35400;
 
 
 // Size of Misago's branding in footer
 // Size of Misago's branding in footer
-@misago-branding-size:           @font-size-large * 1.6;
+@misago-branding-size:           @font-size-large;
 
 
 // Footer links
 // Footer links
 @footer-link-color:              @state-default;
 @footer-link-color:              @state-default;
 @footer-link-hover-color:        @state-hover;
 @footer-link-hover-color:        @state-hover;
 @footer-link-active-color:       @state-clicked;
 @footer-link-active-color:       @state-clicked;
-
-
-//== Buttons
-//
-//## For each of Bootstrap's buttons, define text, background and border color.
-
-@btn-font-weight:                normal;
-
-
-@btn-default-color:              #777;
-@btn-default-bg:                 darken(@body-bg, 5%);
-@btn-default-border:             darken(@btn-default-bg, 10%);
-
-@btn-default-hover-color:        @text-color;
-@btn-default-hover-bg:           darken(@body-bg, 2%);
-@btn-default-hover-border:       #999;
-
-@btn-default-active-color:       @text-color;
-@btn-default-active-bg:          darken(@body-bg, 6%);
-@btn-default-active-border:      #999;
-
-@btn-primary-color:              #fff;
-@btn-primary-bg:                 @brand-primary;
-@btn-primary-border:             darken(@btn-primary-bg, 15%);
-
-@btn-success-color:              #fff;
-@btn-success-bg:                 @brand-success;
-@btn-success-border:             darken(@btn-success-bg, 15%);
-
-@btn-warning-color:              #fff;
-@btn-warning-bg:                 @brand-warning;
-@btn-warning-border:             darken(@btn-warning-bg, 15%);
-
-@btn-danger-color:               #fff;
-@btn-danger-bg:                  @brand-danger;
-@btn-danger-border:              darken(@btn-danger-bg, 15%);
-
-
-//== Forms
-//
-@legend-color:                          darken(@body-bg, 40%);
-@field-help-block-color:                darken(@body-bg, 50%);
-
-//## Misago wraps forms into panels
-@form-panel-bg:                         #fff;
-@form-panel-border:                     darken(@body-bg, 15%);
-@form-panel-shadow:                     darken(@body-bg, 5%);
-@form-panel-footer-bg:                  darken(@body-bg, 1%);
-@form-panel-padding-vertical:           (@padding-large-vertical * 1.5);
-@form-panel-padding-horizontal:         @padding-large-horizontal;
-@form-panel-padding:                    @form-panel-padding-vertical @form-panel-padding-horizontal;
-
-//## Misago Yes-No switch
-@yesno-switch-default:                  lighten(@gray-light, 25%);
-@yesno-switch-active:                   @brand-primary;
-
-
-//== Panels
-//
-//##
-
-@panel-bg:                    #fff;
-@panel-shadow:                darken(@body-bg, 5%);
-@panel-body-padding:          15px;
-
-@panel-default-border:        darken(@body-bg, 15%);
-
-//** Border color for elements within panels
-@panel-inner-border:          darken(@body-bg, 8%);
-@panel-footer-bg:             @panel-bg;
-
-//** Table panels
-@table-panel-bg:                        @panel-bg;
-@table-panel-border:                    @panel-default-border;
-@table-panel-shadow:                    @panel-shadow;
-
-@table-row-highlight:                   fadeOut(@brand-warning, 90%);
-
-@table-header-color:                    @gray;
-@table-header-bg:                       darken(@body-bg, 5%);
-@table-header-border:                   darken(@body-bg, 15%);
-
-//** User cards
-@user-card-bg:                         @body-bg;
-@user-card-border:                     darken(@body-bg, 15%);
-@user-card-shadow:                     darken(@body-bg, 15%);
-
-@user-card-hover-border:               fadeOut(@state-hover, 50%);
-@user-card-hover-shadow:               fadeOut(@state-hover, 50%);
-
-@user-card-active-border:              @state-clicked;
-@user-card-active-shadow:              @state-clicked;
-
-//** Post panels
-@post-panel-bg:                        @panel-bg;
-@post-panel-border:                    @panel-default-border;
-
-@post-active-panel-bg:                 lighten(#3498db, 44%);
-@post-active-panel-border:             lighten(#3498db, 38%);
-
-
-//== Form states and alerts
-//
-//## Define colors for form feedback states and, by default, alerts.
-
-@state-success-text:             #27ae60;
-@state-success-text-contrast:    #fff;
-@state-success-bg:               #2ecc71;
-
-@state-info-text:                @brand-primary;
-@state-info-text-contrast:       #fff;
-@state-info-bg:                  @brand-primary;
-
-@state-warning-text:             #e67e22;
-@state-warning-text-contrast:    #fff;
-@state-warning-bg:               #e67e22;
-
-@state-danger-text:              #c0392b;
-@state-danger-text-contrast:     #fff;
-@state-danger-bg:                darken(#e74c3c, 12%);
-
-
-//== Alerts
-//
-//## Define alert colors, border radius, and padding.
-
-@alert-padding:               14px;
-@alert-border-radius:         @border-radius-large;
-
-@alert-success-bg:            @state-success-bg;
-@alert-success-text:          @state-success-text-contrast;
-
-@alert-info-bg:               @state-info-bg;
-@alert-info-text:             @state-info-text-contrast;
-
-@alert-warning-bg:            @state-warning-bg;
-@alert-warning-text:          @state-warning-text-contrast;
-
-@alert-danger-bg:             @state-danger-bg;
-@alert-danger-text:           @state-danger-text-contrast;
-
-@alert-default-bg:            @gray-lighter;
-@alert-default-text:          @gray;
-
-
-//== 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;

BIN
misago/static/misago/img/misago_logo.png


+ 76 - 0
misago/templates/misago/admin/bans/form.html

@@ -0,0 +1,76 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% if target.pk %}
+{% trans target.banned_value %}
+{% else %}
+{% trans "New ban" %}
+{% endif %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% if target.pk %}
+{% trans target.banned_value %}
+{% else %}
+{% trans "New ban" %}
+{% endif %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% if target.pk %}
+  {% trans target.banned_value %}
+  {% else %}
+  {% trans "New ban" %}
+  {% endif %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Ban settings" %}</legend>
+
+    {% form_row form.check_type label_class field_class %}
+    {% form_row form.banned_value label_class field_class %}
+    {% form_row form.expires_on label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Messages" %}</legend>
+
+    {% form_row form.user_message label_class field_class %}
+    {% form_row form.staff_message label_class field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('#id_valid_until').datetimepicker({
+      language: $('html').attr('lang'),
+      pickTime: false
+    });
+  });
+</script>
+{% endblock %}

+ 117 - 0
misago/templates/misago/admin/bans/list.html

@@ -0,0 +1,117 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n misago_forms %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:users:bans:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New ban" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th style="width: 25%;">{% trans "Ban" %}</th>
+<th style="width: 160px;">{% trans "Type" %}</th>
+<th>{% trans "Expires on" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td class="item-name">
+  {{ item.banned_value }}
+</td>
+<td>
+  {{ item.test_name }}
+</td>
+<td>
+  {% if item.expires_on %}
+    {% if item.is_expired %}
+      <span class="text-muted tooltip-top" title="{% trans "This ban has expired." %}">
+        {{ item.expires_on|date }}
+        <span class="fa fa-exclamation text-danger"></span>
+      </span>
+    {% else %}
+      <span class="tooltip-top" title="{{ item.expires_on|date:"DATETIME_FORMAT" }}">
+        {{ item.formatted_expiration_date }}
+      </span>
+    {% endif %}
+  {% else %}
+  <em>{% trans "Never" %}</em>
+  {% endif %}
+</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link ban_id=item.id %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  <a href="{% url 'misago:admin:users:bans:edit' ban_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+<td class="row-action">
+  <form action="{% url 'misago:admin:users:bans:delete' ban_id=item.id %}" method="post" class="delete-prompt">
+    <button class="btn btn-danger tooltip-top" title="{% trans "Remove" %}">
+      {% csrf_token %}
+      <span class="fa fa-times"></span>
+    </button>
+  </form>
+</td>
+{% endblock %}
+
+
+{% block emptylist %}
+<td colspan="{{ 6|add:extra_actions_len }}">
+  {% if active_filters %}
+  <p>{% trans "No bans matching search criteria have been found" %}</p>
+  {% else %}
+  <p>{% trans "No bans are currently set." %}</p>
+  {% endif %}
+</td>
+{% endblock emptylist %}
+
+
+{% block javascripts %}
+{{ block.super }}
+<script type="text/javascript">
+  $(function() {
+    $('.delete-prompt').submit(function() {
+      var decision = confirm("{% trans "Are you sure you want to remove this ban?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}
+
+
+{% block modal-title %}
+{% trans "Search bans" %}
+{% endblock modal-title %}
+
+
+{% block modal-body %}
+<div class="row">
+  <div class="col-md-6">
+    {% form_row search_form.check_type %}
+  </div>
+  <div class="col-md-6">
+    {% form_row search_form.value %}
+  </div>
+</div>
+<div class="row">
+  <div class="col-md-12">
+    {% form_row search_form.state %}
+  </div>
+</div>
+{% endblock modal-body %}
+

+ 25 - 0
misago/templates/misago/admin/base.html

@@ -0,0 +1,25 @@
+{% extends "misago/admin/base_thin.html" %}
+{% load pipeline i18n %}
+
+
+{% block body %}
+{% include "misago/admin/navbar.html" %}
+{% include "misago/admin/messages.html" %}
+
+{% block content %}{% endblock %}
+
+<footer class="admin-footer">
+  <div class="misago-branding text-center">
+    <a href="http://misago-project.org">
+      <span class="subscript">powered by</span>
+      <span class="brand-border"><span>m</span></span>isago
+    </a>
+  </div>
+</footer>
+
+{% include "misago/admin/logout.html" %}
+
+{# We include JavaScript at the end of page body so it renders faster #}
+{% javascript 'misago_admin' %}
+{% block javascripts %}{% endblock javascripts %}
+{% endblock %}

+ 26 - 0
misago/templates/misago/admin/base_thin.html

@@ -0,0 +1,26 @@
+{% load pipeline i18n staticfiles %}
+<!DOCTYPE html>
+<html lang="{{ LANGUAGE_CODE }}">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>{% block title %}{% trans "Misago Administration" %}{% endblock %}</title>
+    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
+    <!--[if lt IE 9]>
+      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
+      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
+    <![endif]-->
+    {% stylesheet 'misago_admin' %}
+    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="{% static 'apple-touch-icon-144-precomposed.png' %}">
+    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="{% static 'apple-touch-icon-114-precomposed.png' %}">
+    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="{% static 'apple-touch-icon-72-precomposed.png' %}">
+    <link rel="apple-touch-icon-precomposed" href="{% static 'apple-touch-icon-57-precomposed.png' %}">
+    <link rel="shortcut icon" href="{% static 'favicon.ico' %}">
+  </head>
+  <body>
+
+    {% block body %}{% endblock %}
+
+  </body>
+</html>

+ 70 - 0
misago/templates/misago/admin/conf/group.html

@@ -0,0 +1,70 @@
+{% extends "misago/admin/conf/index.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}{{ active_group.name }} | {{ block.super }}{% endblock %}
+
+
+{% block header %}
+  <div class="main">
+    <span class="fa fa-cogs">
+    <a href="{% url 'misago:admin:settings:index' %}">{% trans "Settings" %}</a>
+  </div>
+  <div class="sub">
+    <span class="fa fa-chevron-right"></span>
+    {{ active_group.name }}
+  </div>
+{% endblock header%}
+
+
+{% block action %}
+<div class="form-panel">
+  <form role="form" method="post" class="form-horizontal">
+    {% csrf_token %}
+
+    <div class="form-header">
+      <h1>{{ active_group.name }} </h1>
+      {% if active_group.description %}
+      <p>{{ active_group.description }}</p>
+      {% endif %}
+    </div>
+
+    {% with label_class="col-md-3" field_class="col-md-9" %}
+      {% if use_single_form_template %}
+      <div class="form-body no-fieldsets">
+        {% for field in fieldsets.0.form %}
+        {% form_row field label_class field_class %}
+        {% endfor %}
+      </div>
+      {% else %}
+      <div class="form-body">
+        {% for fieldset in fieldsets %}
+        <fieldset>
+          {% if fieldset.legend %}
+          <legend>{{ fieldset.legend }}</legend>
+          {% endif %}
+
+          {% for field in fieldset.form %}
+          {% form_row field label_class field_class %}
+          {% endfor %}
+
+        </fieldset>
+        {% endfor %}
+      </div>
+      {% endif %}
+    {% endwith %}
+
+    <div class="form-footer">
+      <div class="row">
+        <div class="col-md-offset-3">
+
+          <button class="btn btn-primary">{% trans "Change settings" %}</button>
+          <a href="{% url 'misago:admin:settings:index' %}" class="btn btn-default">{% trans "Cancel" %}</a>
+
+        </div>
+      </div>
+    </div>
+
+  </form>
+</div>
+{% endblock action %}

+ 57 - 0
misago/templates/misago/admin/conf/index.html

@@ -0,0 +1,57 @@
+{% extends "misago/admin/base.html" %}
+{% load i18n %}
+
+
+{% block title %}{% trans "Settings" %} | {{ block.super }}{% endblock %}
+
+
+{% block content %}
+<div class="page-header">
+  <div class="container">
+    <h1>
+      {% block header %}
+        <span class="fa fa-cogs">
+        {% trans "Settings" %}
+      {% endblock %}
+    </h1>
+  </div>
+</div>
+
+<div class="container">
+  <div class="row">
+    <div class="col-md-3">
+
+      <ul class="nav nav-side">
+        {% for group in settings_groups %}
+        <li {% if group.key == active_group.key %}class="active"{% endif %}>
+          <a href="{% url 'misago:admin:settings:group' group_key=group.key %}">
+            {{ group.name }}
+          </a>
+        </li>
+        {% endfor %}
+      </ul>
+
+    </div><!-- /.col-md-3 -->
+    <div class="col-md-9">
+
+      {% block action %}
+      <div class="list-panel">
+        <div class="list-group">
+
+          {% for group in settings_groups %}
+          <a href="{% url 'misago:admin:settings:group' group_key=group.key %}" class="list-group-item">
+            <h4 class="list-group-item-heading">{{ group.name }}</h4>
+            {% if group.description %}
+            <p class="list-group-item-text">{{ group.description }}</p>
+            {% endif %}
+          </a>
+          {% endfor %}
+
+        </div><!-- /.list-group -->
+      </div>
+      {% endblock action %}
+
+    </div><!-- /.col-md-9 -->
+  </div>
+</div>
+{% endblock content %}

+ 27 - 0
misago/templates/misago/admin/errorpages/403.html

@@ -0,0 +1,27 @@
+{% extends "misago/admin/base.html" %}
+{% load i18n %}
+
+
+{% block title %}{% trans "Page not available" %} | {{ block.super }}{% endblock %}
+
+
+{% block content %}
+<div class="container">
+
+  <div class="error-message">
+
+    <div class="error-icon">
+      <span class="fa fa-ban"></span>
+    </div>
+
+    <h1>{% trans "Requested page is not available." %}</h1>
+    {% if message %}
+    <p>{{ message }}</p>
+    {% else %}
+    <p>{% trans "You don't have permission to access this page." %}</p>
+    {% endif %}
+
+  </div>
+
+</div>
+{% endblock content %}

+ 23 - 0
misago/templates/misago/admin/errorpages/404.html

@@ -0,0 +1,23 @@
+{% extends "misago/admin/base.html" %}
+{% load i18n %}
+
+
+{% block title %}{% trans "Page not found" %} | {{ block.super }}{% endblock %}
+
+
+{% block content %}
+<div class="container">
+
+  <div class="error-message">
+
+    <div class="error-icon">
+      <span class="fa fa-compass"></span>
+    </div>
+
+    <h1>{% trans "Requested page could not be found." %}</h1>
+    <p>{% trans "The link you clicked was incorrect or the page has been moved or deleted." %}</p>
+
+  </div>
+
+</div>
+{% endblock content %}

+ 28 - 0
misago/templates/misago/admin/errorpages/csrf_failure.html

@@ -0,0 +1,28 @@
+{% extends "misago/admin/base_thin.html" %}
+{% load i18n %}
+
+
+{% block title %}{% trans "Request blocked" %} | {{ block.super }}{% endblock %}
+
+
+{% block body %}
+<div class="login-form">
+
+  <div class="form-panel">
+    <div class="form-body no-fieldsets">
+
+      <div class="error-message">
+        <div class="error-icon">
+          <span class="fa fa-exclamation-triangle"></span>
+        </div>
+
+        <h1>{% trans "Suspicious request blocked." %}</h1>
+        <p>{% trans "This is usually caused by your browser not accepting or using outdated cookies." %}</p>
+        <p>{% trans "Check your browser configuration and try again." %}</p>
+      </div>
+
+    </div>
+  </div>
+
+</div>
+{% endblock body %}

+ 24 - 0
misago/templates/misago/admin/errorpages/csrf_failure_authenticated.html

@@ -0,0 +1,24 @@
+{% extends "misago/admin/base.html" %}
+{% load i18n %}
+
+
+{% block title %}{% trans "Request blocked" %} | {{ block.super }}{% endblock %}
+
+
+{% block content %}
+<div class="container">
+
+  <div class="error-message">
+
+    <div class="error-icon">
+      <span class="fa fa-exclamation-triangle"></span>
+    </div>
+
+    <h1>{% trans "Suspicious request blocked." %}</h1>
+    <p>{% trans "This is usually caused by your browser not accepting or using outdated cookies." %}</p>
+    <p>{% trans "Check your browser configuration and try again." %}</p>
+
+  </div>
+
+</div>
+{% endblock content %}

+ 59 - 0
misago/templates/misago/admin/forumroles/form.html

@@ -0,0 +1,59 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New role" %}
+{% endif %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New role" %}
+{% endif %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% if target.pk %}
+  {{ target }}
+  {% else %}
+  {% trans "New role" %}
+  {% endif %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+
+  <fieldset>
+    <legend>{% trans "Basic settings" %}</legend>
+
+    {% form_row form.name "col-md-3" "col-md-9" %}
+
+  </fieldset>
+
+  {% for form in perms_forms %}
+  {% include "misago/admin/permissions_table.html" %}
+  {% endfor %}
+
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}

+ 69 - 0
misago/templates/misago/admin/forumroles/forumroles.html

@@ -0,0 +1,69 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load crispy_forms_field i18n %}
+
+
+{% block title %}
+{% blocktrans with forum=target %}
+{{ forum }}: Permissions
+{% endblocktrans %} | {{ block.super }}
+{% endblock title%}
+
+
+{% block page-header %}
+{{ block.super }}
+<div class="sub">
+  <span class="fa fa-chevron-right"></span>
+  {% blocktrans with forum=target %}
+  {{ forum }}: Permissions
+  {% endblocktrans %}
+</div>
+{% endblock page-header %}
+
+
+{% block view %}
+<form method="post" role="form">
+  {% csrf_token %}
+  <div class="table-panel">
+    <table class="table">
+      <tr>
+        <th>{% trans "Forum" %}</ht>
+        <th class="col-md-6">{% trans "Permissions" %}</ht>
+      </tr>
+
+      {% for form in forms %}
+      <tr>
+        <td class="item-name">
+          {{ form.role }}
+        </td>
+        <td>
+          {% crispy_field form.forum_role %}
+        </td>
+      </tr>
+      {% endfor %}
+    </table>
+    <div class="table-footer">
+      <div class="row">
+        <div class="col-md-offset-6">
+
+          <button class="btn btn-primary">{% trans "Save changes" %}</button>
+          <button class="btn btn-success" name="stay" value="1">{% trans "Save and keep editing" %}</button>
+          <a href="{% url root_link %}" class="btn btn-default btn-cancel">{% trans "Cancel" %}</a>
+
+        </div>
+      </div>
+    </div>
+  </div><!-- /.table-panel -->
+</form>
+{% endblock view %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('.btn-cancel').click(function() {
+      var decision = confirm("{% trans "Are you sure you want to abandon changes?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}

+ 58 - 0
misago/templates/misago/admin/forumroles/list.html

@@ -0,0 +1,58 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:permissions:forums:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New role" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th>{% trans "Forum role" %}</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td class="item-name">
+  {{ item }}
+</td>
+<td class="row-action">
+  <a href="{% url 'misago:admin:permissions:forums:edit' role_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+<td class="row-action">
+  <form action="{% url 'misago:admin:permissions:forums:delete' role_id=item.id %}" method="post" class="delete-prompt">
+    <button class="btn btn-danger tooltip-top" title="{% trans "Delete" %}">
+      {% csrf_token %}
+      <span class="fa fa-times"></span>
+    </button>
+  </form>
+</td>
+{% endblock %}
+
+
+{% block emptylist %}
+<td colspan="3">
+  <p>{% trans "No forum roles are currently defined." %}</p>
+</td>
+{% endblock emptylist %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('.delete-prompt').submit(function() {
+      var decision = confirm("{% trans "Are you sure you want to delete this role?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}

+ 79 - 0
misago/templates/misago/admin/forumroles/roleforums.html

@@ -0,0 +1,79 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load crispy_forms_field i18n %}
+
+
+{% block title %}
+{% blocktrans with role=target %}
+{{ role }}: Forum permissions
+{% endblocktrans %} | {{ block.super }}
+{% endblock title%}
+
+
+{% block page-header %}
+{{ block.super }}
+<div class="sub">
+  <span class="fa fa-chevron-right"></span>
+  {% blocktrans with role=target %}
+  {{ role }}: Forum permissions
+  {% endblocktrans %}
+</div>
+{% endblock page-header %}
+
+
+{% block view %}
+<form method="post" role="form">
+  {% csrf_token %}
+  <div class="table-panel">
+    <table class="table">
+      <tr>
+        <th>{% trans "Forum" %}</ht>
+        <th class="col-md-6">{% trans "Permissions" %}</ht>
+      </tr>
+
+      {% for form in forms %}
+      <tr>
+        <td class="item-name">
+          {% for i in form.forum.level_range %}
+          &nbsp;&nbsp;&nbsp;&nbsp;
+          {% endfor %}
+          {% if form.forum.role == 'category' %}
+          <span class="fa fa-folder-open tooltip-top" title="{% trans "Category" %}"></span>
+          {% elif form.forum.role == 'forum' %}
+          <span class="fa fa-comments-o tooltip-top" title="{% trans "Forum" %}"></span>
+          {% elif form.forum.role == 'redirect' %}
+          <span class="fa fa-link tooltip-top" title="{% trans "Redirect" %}"></span>
+          {% endif %}
+          {{ form.forum }}
+        </td>
+        <td>
+          {% crispy_field form.role %}
+        </td>
+      </tr>
+      {% endfor %}
+    </table>
+    <div class="table-footer">
+      <div class="row">
+        <div class="col-md-offset-6">
+
+          <button class="btn btn-primary">{% trans "Save changes" %}</button>
+          <button class="btn btn-success" name="stay" value="1">{% trans "Save and keep editing" %}</button>
+          <a href="{% url root_link %}" class="btn btn-default btn-cancel">{% trans "Cancel" %}</a>
+
+        </div>
+      </div>
+    </div>
+  </div><!-- /.table-panel -->
+</form>
+{% endblock view %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('.btn-cancel').click(function() {
+      var decision = confirm("{% trans "Are you sure you want to abandon changes?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}

+ 45 - 0
misago/templates/misago/admin/forums/delete.html

@@ -0,0 +1,45 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load crispy_forms_filters i18n %}
+
+
+{% block title %}
+{% blocktrans with forum=target.name %}
+Delete forum: {{forum}}
+{% endblocktrans %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% blocktrans with forum=target.name %}
+Delete forum: {{forum}}
+{% endblocktrans %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% blocktrans with forum=target.name %}
+  Delete forum: {{forum}}
+  {% endblocktrans %}
+</h1>
+{% endblock %}
+
+
+{% block form-body %}
+<div class="form-body">
+  <fieldset>
+    <legend>{% trans "Forum contents" %}</legend>
+
+    {% if not form.instance.is_leaf_node %}
+    {{ form.move_children_to|as_crispy_field }}
+    {% endif %}
+    {{ form.move_threads_to|as_crispy_field }}
+
+  </fieldset>
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer %}
+<button class="btn btn-danger">{% trans "Delete forum" %}</button>
+{% endblock %}

+ 80 - 0
misago/templates/misago/admin/forums/form.html

@@ -0,0 +1,80 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New forum" %}
+{% endif %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New forum" %}
+{% endif %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% if target.pk %}
+  {{ target }}
+  {% else %}
+  {% trans "New forum" %}
+  {% endif %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Role and position" %}</legend>
+
+    {% form_row form.new_parent label_class field_class %}
+    {% form_row form.role label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Display" %}</legend>
+
+    {% form_row form.name label_class field_class %}
+    {% form_row form.description label_class field_class %}
+    {% form_row form.css_class label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Behaviour" %}</legend>
+
+    {% form_row form.copy_permissions label_class field_class %}
+    {% form_row form.redirect_url label_class field_class %}
+    {% form_row form.is_closed label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Prune threads" %}</legend>
+
+    {% form_row form.prune_started_after label_class field_class %}
+    {% form_row form.prune_replied_after label_class field_class %}
+    {% form_row form.archive_pruned_in label_class field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}

+ 89 - 0
misago/templates/misago/admin/forums/list.html

@@ -0,0 +1,89 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:forums:nodes:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New forum" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th>{% trans "Forum" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th>&nbsp;</th>
+<th>&nbsp;</th>
+<th>&nbsp;</th>
+<th>&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td class="item-name">
+  {% for i in item.level_range %}
+  &nbsp;&nbsp;&nbsp;&nbsp;
+  {% endfor %}
+  {% if item.role == 'category' %}
+  <span class="fa fa-folder-open tooltip-top" title="{% trans "Category" %}"></span>
+  {% elif item.role == 'forum' %}
+  <span class="fa fa-comments-o tooltip-top" title="{% trans "Forum" %}"></span>
+  {% elif item.role == 'redirect' %}
+  <span class="fa fa-link tooltip-top" title="{% trans "Redirect" %}"></span>
+  {% endif %}
+  {{ item }}
+</td>
+<td class="row-action">
+  {% if not item.last %}
+  <form action="{% url 'misago:admin:forums:nodes:down' forum_id=item.id %}" method="post">
+    <button class="btn btn-default tooltip-top" title="{% trans "Move down" %}">
+      {% csrf_token %}
+      <span class="fa fa-chevron-down"></span>
+    </button>
+  </form>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td class="row-action">
+  {% if not item.first %}
+  <form action="{% url 'misago:admin:forums:nodes:up' forum_id=item.id %}" method="post">
+    <button class="btn btn-default tooltip-top" title="{% trans "Move up" %}">
+      {% csrf_token %}
+      <span class="fa fa-chevron-up"></span>
+    </button>
+  </form>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link forum_id=item.id %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  <a href="{% url 'misago:admin:forums:nodes:edit' forum_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+<td class="row-action">
+  <a href="{% url 'misago:admin:forums:nodes:delete' forum_id=item.id %}" class="btn btn-danger tooltip-top" title="{% trans "Delete" %}">
+    <span class="fa fa-times"></span>
+  </a>
+</td>
+{% endblock %}
+
+
+{% block emptylist %}
+<td colspan="{{ 5|add:extra_actions_len }}">
+  <p>{% trans "No forums exist." %}</p>
+</td>
+{% endblock emptylist %}

+ 26 - 0
misago/templates/misago/admin/generic/base.html

@@ -0,0 +1,26 @@
+{% extends "misago/admin/base.html" %}
+{% load i18n %}
+
+
+{% block content %}
+<div class="page-header">
+  <div class="container">
+    <h1>
+      {% block page-header %}
+      <div class="main">
+        <a href="{{ active_link.link }}">
+          <span class="{{ active_link.icon }}">
+          {{ active_link.name }}
+        </a>
+      </div>
+      {% endblock page-header %}
+    </h1>
+    {% block page-actions %}{% endblock %}
+  </div>
+</div>
+
+<div class="container">
+  {% block view %}
+  {% endblock view %}
+</div>
+{% endblock content %}

+ 65 - 0
misago/templates/misago/admin/generic/form.html

@@ -0,0 +1,65 @@
+{% extends "misago/admin/generic/base.html" %}
+{% load i18n %}
+
+
+{% block page-header %}
+{{ block.super }}
+<div class="sub">
+  <span class="fa fa-chevron-right"></span>
+  {% block page-target %}{% endblock page-target %}
+</div>
+{% endblock page-header %}
+
+
+{% block view %}
+<div class="row">
+  <div class="col-xs-12 col-md-8 col-md-offset-2">
+
+    <div class="form-panel">
+      <form role="form" method="post" {% block form-extra %}{% endblock form-extra%}>
+        {% csrf_token %}
+
+        <div class="form-header">
+          {% block form-header %}{% endblock %}
+        </div>
+
+        {% if form.is_bound and not form.is_valid %}
+        <div class="form-errors-block">
+          <span class="fa fa-exclamation-triangle"></span>
+          <ul class="list-unstyled">
+            {% for error in form.non_field_errors %}
+            <li>{{ error }}</li>
+            {% empty %}
+            <li>{% trans "Form has errors." %}</li>
+            {% endfor %}
+          </ul>
+        </div>
+        {% endif %}
+
+        {% block form-body %}{% endblock %}
+
+        <div class="form-footer">
+          <div class="row">
+            <div class="{% block form-footer-class %}col-xs-12{% endblock form-footer-class %}">
+
+              {% block form-footer %}
+              {% if target and target.pk %}
+              <button class="btn btn-primary">{% trans "Save changes" %}</button>
+              <button class="btn btn-success" name="stay" value="1">{% trans "Save and keep editing" %}</button>
+              {% else %}
+              <button class="btn btn-primary">{% trans "Save" %}</button>
+              <button class="btn btn-success" name="stay" value="1">{% trans "Save and add another" %}</button>
+              {% endif %}
+              {% endblock %}
+              <a href="{% url root_link %}" class="btn btn-default">{% trans "Cancel" %}</a>
+
+            </div>
+          </div>
+        </div>
+
+      </form>
+    </div><!-- /.form-panel -->
+
+  </div>
+</div>
+{% endblock view %}

+ 189 - 0
misago/templates/misago/admin/generic/list.html

@@ -0,0 +1,189 @@
+{% extends "misago/admin/generic/base.html" %}
+{% load i18n %}
+
+
+{% block title %}
+{{ active_link.name }} | {{ block.super }}
+{% endblock title%}
+
+
+{% block view %}
+{% if paginator or order_by or search_form or mass_actions %}
+<div class="table-actions">
+
+  {% if paginator %}
+  {% include "misago/admin/generic/paginator.html" %}
+  {% endif%}
+
+  {% if order_by %}
+  <div class="btn-group pull-left">
+    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+      {% trans "Sort:" %} <span class="fa fa-sort-numeric-{{ order.type }}"></span> <strong>{{ order.name }}</strong>
+    </button>
+    <ul class="dropdown-menu" role="menu">
+      <li class="dropdown-title">
+        {% trans "Change sorting to:" %}
+      </li>
+      {% for order in order_by %}
+      <li>
+        <form method="get">
+          <input type="hidden" name="sort" value="{{ order.order_by }}">
+          <input type="hidden" name="direction" value="{{ order.type }}">
+          {% for name, value in query_filters.items %}
+          <input type="hidden" name="{{ name }}" value="{{ value }}">
+          {% endfor %}
+          <button type="submit">
+            <span class="fa fa-sort-numeric-{{ order.type }}"></span>
+            {{ order.name }}
+          </button>
+        </form>
+      </li>
+      {% endfor %}
+    </ul>
+  </div>
+  {% endif %}
+
+  {% if search_form %}
+    <button class="btn btn-{% if active_filters %}success{% else %}default{% endif %} pull-left" data-toggle="modal" data-target="#filter-modal">
+      {% if active_filters %}
+      <span class="fa fa-check"></span>
+      {% trans "Change search" %}
+      {% else %}
+      <span class="fa fa-search"></span>
+      {% trans "Search list" %}
+      {% endif %}
+    </button>
+
+    {% if active_filters %}
+    <form method="get" class="pull-left">
+      <input type="hidden" name="clear_filters" value="1">
+      {% for name, value in query_order.items %}
+      <input type="hidden" name="{{ name }}" value="{{ value }}">
+      {% endfor %}
+      <button type="submit" class="btn btn-default">
+        <span class="fa fa-times"></span>
+        {% trans "Remove search" %}
+      </button>
+    </form>
+    {% endif %}
+  {% endif %}
+
+  {% if mass_actions %}
+  <button type="button" class="btn btn-default pull-right master-checkbox">
+    <span class="fa fa-check"></span>
+  </button>
+  <div class="btn-group pull-right">
+    <form id="mass-action" action="{{ querystring }}" method="post">
+      <button type="button" class="btn btn-default dropdown-toggle mass-controller" data-toggle="dropdown">
+        <span class="fa fa-gears"></span>
+        {% trans "With selected" %}
+      </button>
+      {% csrf_token %}
+      <ul class="dropdown-menu" role="menu">
+        {% for action in mass_actions %}
+        <li>
+          <button type="submit" name="action" value="{{ action.action }}" {% if action.confirmation %}data-confirmation="{{ action.confirmation }}"{% endif %}>
+            <span class="{{ action.icon }}"></span>
+            {{ action.name }}
+          </button>
+        </li>
+        {% endfor %}
+      </ul>
+    </form>
+  </div>
+  {% endif %}
+
+</div><!-- /.table-actions -->
+{% endif %}
+
+<div class="table-panel">
+  <table class="table">
+    <tr>
+      {% block table-header %}
+      {% endblock table-header %}
+      {% if mass_actions %}
+      <th class="width: 1%;">&nbsp;</th>
+      {% endif %}
+    </tr>
+
+    {% block table-items %}
+    {% for item in items %}
+    <tr>
+      {% block table-row %}{% endblock table-row %}
+      {% if mass_actions %}
+      <td class="row-select">
+        <label>
+          <input type="checkbox" form="mass-action" name="selected_items" value="{{ item.pk }}" {% if item.pk in selected_items %} checked{% endif %}>
+        </label>
+      </td>
+      {% endif %}
+    </tr>
+    {% empty %}
+    <tr class="message-row">
+      {% block emptylist %}
+      {% endblock emptylist %}
+    </tr>
+    {% endfor %}
+    {% endblock table-items %}
+  </table>
+</div><!-- /.table-panel -->
+
+{% if paginator %}
+<div class="table-actions">
+  {% include "misago/admin/generic/paginator.html" %}
+</div><!-- /.table-actions -->
+{% endif %}
+{% endblock view %}
+
+
+{% block content %}
+{{ block.super }}
+{% if search_form %}
+<div class="modal fade" id="filter-modal" tabindex="-1" role="dialog" aria-labelledby="filter-modal-label" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <h4 class="modal-title" id="filter-modal-label">
+        {% block modal-title %}
+        {% endblock modal-title %}
+        </h4>
+      </div>
+      <form method="GET">
+        <input type="hidden" name="set_filters" value="1">
+        {% for name, value in query_order.items %}
+        <input type="hidden" name="{{ name }}" value="{{ value }}">
+        {% endfor %}
+
+        <div class="modal-body">
+        {% block modal-body %}
+        {% endblock modal-body %}
+        </div>
+        <div class="modal-footer">
+        {% block modal-footer %}
+        <button type="button" class="btn btn-default" data-dismiss="modal">
+          {% trans "Close" %}
+        </button>
+        <button type="submit" class="btn btn-primary">
+          {% trans "Save changes" %}
+        </button>
+        {% endblock modal-footer %}
+        </div>
+
+      </form>
+    </div>
+  </div>
+</div>
+{% endif %}
+{% endblock content%}
+
+
+{% block javascripts %}
+{% if mass_actions %}
+<script type="text/javascript">
+  $(function() {
+    tableMassActions("{{ empty_selection_label }}", "{{ selection_label }}");
+  });
+</script>
+{% endif %}
+{% endblock javascripts %}

+ 37 - 0
misago/templates/misago/admin/generic/paginator.html

@@ -0,0 +1,37 @@
+{% load i18n%}
+
+<ul class="pager pull-left">
+  <li class="page">
+    {% blocktrans with page=page.number pages=paginator.num_pages %}
+    Page {{ page }} of {{ pages }}
+    {% endblocktrans %}
+  </li>
+  {% if page.has_previous %}
+    <li>
+      <a href="{% url root_link %}{{ querystring }}" class="tooltip-top" title="{% trans "Go to first page" %}">
+        {% trans "First" %}
+      </a>
+    </li>
+    {% if page.number > 2 %}
+    <li>
+      <a href="{% url root_link page=page.previous_page_number %}{{ querystring }}" class="tooltip-top" title="{% trans "Go to previous page" %}">
+        <span class="glyphicon glyphicon-chevron-left"></span>
+      </a>
+    </li>
+    {% endif %}
+  {% endif %}
+  {% if page.has_next %}
+    {% if page.next_page_number < paginator.num_pages %}
+    <li>
+      <a href="{% url root_link page=page.next_page_number %}{{ querystring }}" class="tooltip-top" title="{% trans "Go to next page" %}">
+        <span class="glyphicon glyphicon-chevron-right"></span>
+      </a>
+    </li>
+    {% endif %}
+    <li>
+      <a href="{% url root_link page=paginator.num_pages %}{{ querystring }}" class="tooltip-top" title="{% trans "Go to last page" %}">
+        {% trans "Last" %}
+      </a>
+    </li>
+  {% endif %}
+</ul>

+ 133 - 0
misago/templates/misago/admin/index.html

@@ -0,0 +1,133 @@
+{% extends "misago/admin/base.html" %}
+{% load i18n %}
+
+
+{% block title %}{% trans "Home" %} | {{ block.super }}{% endblock %}
+
+
+{% block content %}
+<div class="page-header">
+  <div class="container">
+    <h1>
+      <span class="fa fa-home">
+      {% trans "Administration Home" %}
+    </h1>
+  </div>
+</div>
+
+<div class="container">
+  <div class="row">
+    <div class="col-md-8">
+
+
+
+    </div>
+    <div class="col-md-4">
+
+      <table class="table version-check">
+        <thead>
+          <tr>
+            <th colspan="2">
+              <h4>
+                <span class="fa fa-github"></span>
+                {% trans "Misago version" %}
+              </h4>
+            </th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td class="text-center">
+              {% if version_check %}
+              <p class="lead text-{% if version_check.is_error %}error{% else %}success{% endif %}">
+                {% if version_check.is_error %}
+                <span class="fa fa-times fa-lg fa-fw"></span>
+                {% else %}
+                <span class="fa fa-check fa-lg fa-fw"></span>
+                {% endif %}
+                {{ version_check.message }}
+              </p>
+              {% else %}
+              <form method="POST">
+                {% csrf_token %}
+                <button type="submit" class="btn btn-default">
+                  <span class="fa fa-question-circle fa-fw"></span>
+                  <span class="name">{% trans "Check version" %}</span>
+                </button>
+              </form>
+              {% endif %}
+            </td>
+          </tr>
+        </tbody>
+      </table>
+
+      <table class="table">
+        <thead>
+          <tr>
+            <th colspan="2">
+              <h4>
+                <span class="fa fa-database"></span>
+                {% trans "DB Contents" %}
+              </h4>
+            </th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td>{% trans "Threads" %}</td>
+            <td>{{ db_stats.threads }}</td>
+          </tr>
+          <tr>
+            <td>{% trans "Posts" %}</td>
+            <td>{{ db_stats.posts }}</td>
+          </tr>
+          <tr>
+            <td>{% trans "Users" %}</td>
+            <td>{{ db_stats.users }}</td>
+          </tr>
+          {% if db_stats.inactive_users %}
+          <tr>
+            <td>{% trans "Inactive users" %}</td>
+            <td>
+              <a href="{% url "misago:admin:users:accounts:index" %}?inactive=1">{{ db_stats.inactive_users }}</a>
+            </td>
+          </tr>
+          {% endif %}
+        </tbody>
+      </table>
+
+    </div>
+  </div>
+</div>
+{% endblock content %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function () {
+    var $version_check = $('.version-check');
+    var $outcome = $version_check.find('td');
+
+    $version_check.find('form').submit(function() {
+      var $form = $(this);
+      var $button = $(this).find("button");
+      $button.attr("disabled", "disabled");
+      $button.find('.fa').attr("class", "fa fa-refresh fa-fw fa-spin");
+      $button.find('.name').text("{% trans "Checking..." %}");
+
+      $.post("{% url 'misago:admin:check_version' %}", $form.serialize(), function(data) {
+        if (data.is_error) {
+          var $message = $('<p class="lead text-danger"><span class="fa fa-times fa-lg fa-fw"></span></p>');
+        } else {
+          var $message = $('<p class="lead text-success"><span class="fa fa-check fa-lg fa-fw"></span></p>');
+        }
+        $message.append(" " + data.message);
+        $form.fadeOut();
+        $outcome.html($message);
+      });
+
+      return false;
+    });
+  });
+</script>
+{% endblock javascripts %}

+ 62 - 0
misago/templates/misago/admin/labels/form.html

@@ -0,0 +1,62 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New label" %}
+{% endif %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New label" %}
+{% endif %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% if target.pk %}
+  {{ target }}
+  {% else %}
+  {% trans "New label" %}
+  {% endif %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Name and appearance" %}</legend>
+
+    {% form_row form.name label_class field_class %}
+    {% form_row form.css_class label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Availability" %}</legend>
+
+    {% form_row form.forums label_class field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}

+ 70 - 0
misago/templates/misago/admin/labels/list.html

@@ -0,0 +1,70 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:forums:labels:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New label" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th>{% trans "Label" %}</th>
+<th style="width: 40%;">{% trans "CSS class" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td class="item-name">
+  {{ item }}
+</td>
+<td>{% if item.css_class %}{{ item.css_class }}{% else %}&nbsp;{% endif %}</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link label_id=item.id %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  <a href="{% url 'misago:admin:forums:labels:edit' label_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+<td class="row-action">
+  <form action="{% url 'misago:admin:forums:labels:delete' label_id=item.id %}" method="post" class="delete-prompt">
+    <button class="btn btn-danger tooltip-top" title="{% trans "Delete" %}">
+      {% csrf_token %}
+      <span class="fa fa-times"></span>
+    </button>
+  </form>
+</td>
+{% endblock %}
+
+
+{% block emptylist %}
+<td colspan="{{ 4|add:extra_actions_len }}">
+  <p>{% trans "No thread labels are currently defined." %}</p>
+</td>
+{% endblock emptylist %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('.delete-prompt').submit(function() {
+      var decision = confirm("{% trans "Are you sure you want to delete this label?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}

+ 78 - 0
misago/templates/misago/admin/login.html

@@ -0,0 +1,78 @@
+{% extends "misago/admin/base_thin.html" %}
+{% load i18n staticfiles %}
+
+
+{% block title %}{% trans "Log in" %} | {% if target == "django" %}{% trans "Django Admin" %}{% else %}{% trans "Misago Admin" %}{% endif %}{% endblock %}
+
+
+{% block body %}
+<div class="login-form">
+
+  {% if target == "misago" %}
+  <div class="form-admin-logo">
+    <img src="{% static 'misago/admin/img/misago.png' %}" alt="Misago">
+  </div>
+  {% elif target == "django" %}
+  <div class="form-admin-logo">
+    <img src="{% static 'misago/admin/img/django.png' %}" alt="Django">
+  </div>
+  {% endif  %}
+
+  <div class="form-panel">
+    <form method="POST" role="form">
+      {% csrf_token %}
+
+      <div class="form-header">
+        <h1>{% trans "Administration" %}</h1>
+      </div>
+
+      <div class="form-body no-fieldsets">
+
+        {% for error in form.non_field_errors %}
+        <div class="misago-alerts">
+          <p class="alert alert-danger lead">
+            {{ error }}
+            <br>{% trans "Please try again." %}
+          </p>
+        </div>
+        {% endfor %}
+        {% for message in messages %}
+        <div class="misago-alerts">
+          {% if 'success' in message.tags %}
+          <p class="alert alert-success lead">
+          {% elif 'warning' in message.tags %}
+          <p class="alert alert-warning lead">
+          {% elif 'error' in message.tags %}
+          <p class="alert alert-danger lead">
+          {% else %}
+          <p class="alert alert-info lead">
+          {% endif %}
+            {{ message }}
+          </p>
+        </div>
+        {% endfor %}
+
+        <div class="form-group">
+          <div class="control-input">
+            <input type="text" name="username" class="form-control input-lg" placeholder="{% trans "Username or e-mail" %}" {% if form.username.value %}value="{{ form.username.value }}"{% endif %}>
+          </div>
+        </div>
+        <div class="form-group">
+          <div class="control-input">
+            <input type="password" name="password" class="form-control input-lg" placeholder="{% trans "Password" %}">
+          </div>
+        </div>
+        <div class="form-group">
+          <div class="control-input">
+            <button class="btn btn-primary btn-block btn-lg">{% trans "Sign in" %}</button>
+          </div>
+        </div>
+
+      </div>
+
+
+    </form>
+  </div>
+
+</div>
+{% endblock body %}

+ 43 - 0
misago/templates/misago/admin/logout.html

@@ -0,0 +1,43 @@
+{% load i18n %}
+<!-- Log out modal -->
+<div class="modal fade" id="logout-modal" tabindex="-1" role="dialog" aria-labelledby="logoutModalLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <h4 class="modal-title" id="logoutModalLabel">{% trans "Log out?" %}</h4>
+      </div>
+      <div class="modal-body">
+
+        <div class="row">
+          <div class="col-md-6">
+
+            <form action="{% url 'misago:admin:logout' %}" method="post">
+              {% csrf_token %}
+              <button type="submit" class="btn btn-primary btn-block">
+                <span class="fa fa-lock"></span>
+                {% trans "Log out from admin" %}
+              </button>
+            </form>
+
+          </div>
+          <div class="col-md-6">
+
+            <form action="{% url 'misago:logout' %}" method="post">
+              {% csrf_token %}
+              <button type="submit" class="btn btn-danger btn-block">
+                <span class="fa fa-power-off"></span>
+                {% trans "Log out completely" %}
+              </button>
+            </form>
+
+          </div>
+        </div>
+
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default btn-lg btn-block" data-dismiss="modal">{% trans "Cancel" %}</button>
+      </div>
+    </div>
+  </div>
+</div>

+ 24 - 0
misago/templates/misago/admin/messages.html

@@ -0,0 +1,24 @@
+{% load i18n %}
+{% if messages %}
+<div class="misago-alerts">
+  {% for message in messages %}
+  <div>
+    {% if 'info' in message.tags %}
+    <p class="alert alert-info">
+      <span class="alert-icon fa fa-info-circle"></span>
+    {% elif 'success' in message.tags %}
+    <p class="alert alert-success">
+      <span class="alert-icon fa fa-check-circle"></span>
+    {% elif 'warning' in message.tags %}
+    <p class="alert alert-warning">
+      <span class="alert-icon fa fa-exclamation-triangle"></span>
+    {% elif 'error' in message.tags %}
+    <p class="alert alert-danger">
+      <span class="alert-icon fa fa-times-circle"></span>
+    {% endif %}
+      {{ message }}
+    </p>
+  </div>
+  {% endfor %}
+</div>
+{% endif %}

+ 45 - 0
misago/templates/misago/admin/navbar.html

@@ -0,0 +1,45 @@
+{% load i18n misago_avatars %}
+<div class="navbars-container">
+  <div class="navbar navbar-default navbar-static-top" role="navigation">
+    <div class="container">
+      <a class="navbar-brand" href="{% url 'misago:index' %}"></a>
+      <ul class="nav navbar-nav">
+        {% for node in sections %}
+        <li{% if node.is_active %} class="active"{% endif %}>
+          <a href="{{ node.link }}">
+            <span class="{{ node.icon }}"></span>
+            {{ node.name }}
+          </a>
+        </li>
+        {% endfor %}
+      </ul>
+      <div class="user-nav pull-right">
+        <p class="navbar-text">
+          <a href="{% url 'misago:admin:users:accounts:edit' user_id=user.id %}" class="tooltip-bottom" title="{% trans "Edit your account" %}">
+            <img src="{{ user|avatar:30 }}" alt="{% trans "Your avatar" %}">
+            {{ user }}
+          </a>
+          <a href="#" class="logout" data-toggle="modal" data-target="#logout-modal">
+            <span class="fa fa-power-off"></span>
+          </a>
+        </p>
+      </div>
+    </div>
+  </div>
+  {% if actions %}
+  <div class="navbar navbar-inverse navbar-static-top" role="navigation">
+    <div class="container">
+      <ul class="nav navbar-nav">
+        {% for node in actions %}
+        <li{% if node.is_active %} class="active"{% endif %}>
+          <a href="{{ node.link }}">
+            <span class="{{ node.icon }}"></span>
+            {{ node.name }}
+          </a>
+        </li>
+        {% endfor %}
+      </ul>
+    </div>
+  </div>
+  {% endif %}
+</div>

+ 36 - 0
misago/templates/misago/admin/permissions_table.html

@@ -0,0 +1,36 @@
+{% load crispy_forms_field crispy_forms_tags i18n %}
+<fieldset>
+  <legend>{{ form.legend }}</legend>
+
+  <table class="table table-striped table-permissions">
+    {% for field in form %}
+    <tr{% if field.errors %} class="text-danger"{% endif %}>
+      <td class="col-md-8">
+        <label>{{ field.label }}:</label>
+        {% for error in field.errors %}
+        <p class="small"><strong>{{ error }}</strong></p>
+        {% endfor %}
+        {% if field.help_text %}
+        <p class="text-muted small">{{ field.help_text }}</p>
+        {% endif %}
+      </td>
+      <td>
+        <div class="form-group{% if field.errors %} has-error{% endif %}">
+          {% if field|is_checkboxselectmultiple %}
+            {% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
+          {% endif %}
+
+          {% if field|is_radioselect %}
+            {% include 'bootstrap3/layout/radioselect.html' with hide_help_text=1 %}
+          {% endif %}
+
+          {% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
+          {% crispy_field field %}
+          {% endif %}
+        </div>
+      </td>
+    </tr>
+    {% endfor %}
+  </table>
+
+</fieldset>

+ 71 - 0
misago/templates/misago/admin/ranks/form.html

@@ -0,0 +1,71 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New rank" %}
+{% endif %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New rank" %}
+{% endif %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% if target.pk %}
+  {{ target }}
+  {% else %}
+  {% trans "New rank" %}
+  {% endif %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Name and description" %}</legend>
+
+    {% form_row form.name label_class field_class %}
+    {% form_row form.title label_class field_class %}
+    {% form_row form.description label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Permissions" %}</legend>
+
+    {% form_row form.roles label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Display and visibility" %}</legend>
+
+    {% form_row form.css_class label_class field_class %}
+    {% form_row form.is_tab "col-md-offset-3" field_class %}
+    {% form_row form.is_on_index "col-md-offset-3" field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}

+ 133 - 0
misago/templates/misago/admin/ranks/list.html

@@ -0,0 +1,133 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:users:ranks:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New rank" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th style="width: 25%;">{% trans "Rank" %}</th>
+<th>{% trans "Title" %}</th>
+<th style="width: 120px;">{% trans "Special" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td class="item-name">
+  {{ item }}
+</td>
+<td>
+  {% if item.title %}
+  {% trans item.title %}
+  {% else %}
+  <i class="text-muted">{% trans "No title set" %}</i>
+  {% endif %}
+</td>
+<td class="lead text-muted">
+  {% if item.is_tab %}
+  <div class="fa fa-list tooltip-top" title="{% trans "Has page on users list." %}"></div>
+  {% endif %}
+  {% if item.is_on_index %}
+  <div class="fa fa-bookmark tooltip-top" title="{% trans "Users online displayed on index." %}"></div>
+  {% endif %}
+  {% if item.is_default %}
+  <div class="fa fa-star tooltip-top" title="{% trans "This is default rank assigned to new members." %}"></div>
+  {% endif %}
+</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link rank_id=item.id %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  <a href="{% url 'misago:admin:users:ranks:users' rank_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Users with rank" %}">
+    <span class="fa fa-users"></span>
+  </a>
+</td>
+<td class="row-action">
+  {% if not item.is_default %}
+  <form action="{% url 'misago:admin:users:ranks:default' rank_id=item.id %}" method="post">
+    <button class="btn btn-warning tooltip-top" title="{% trans "Make default" %}">
+      {% csrf_token %}
+      <span class="fa fa-star"></span>
+    </button>
+  </form>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td class="row-action">
+  {% if not forloop.last %}
+  <form action="{% url 'misago:admin:users:ranks:down' rank_id=item.id %}" method="post">
+    <button class="btn btn-default tooltip-top" title="{% trans "Move down" %}">
+      {% csrf_token %}
+      <span class="fa fa-chevron-down"></span>
+    </button>
+  </form>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td class="row-action">
+  {% if not forloop.first %}
+  <form action="{% url 'misago:admin:users:ranks:up' rank_id=item.id %}" method="post">
+    <button class="btn btn-default tooltip-top" title="{% trans "Move up" %}">
+      {% csrf_token %}
+      <span class="fa fa-chevron-up"></span>
+    </button>
+  </form>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td class="row-action">
+  <a href="{% url 'misago:admin:users:ranks:edit' rank_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+<td class="row-action">
+  <form action="{% url 'misago:admin:users:ranks:delete' rank_id=item.id %}" method="post" class="delete-prompt">
+    <button class="btn btn-danger tooltip-top" title="{% trans "Delete" %}">
+      {% csrf_token %}
+      <span class="fa fa-times"></span>
+    </button>
+  </form>
+</td>
+{% endblock %}
+
+
+{% block emptylist %}
+<td colspan="{{ 8|add:extra_actions_len }}">
+  <p>{% trans "No ranks are currently defined." %}</p>
+</td>
+{% endblock emptylist %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('.delete-prompt').submit(function() {
+      var decision = confirm("{% trans "Are you sure you want to delete this rank?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}

+ 59 - 0
misago/templates/misago/admin/roles/form.html

@@ -0,0 +1,59 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New role" %}
+{% endif %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New role" %}
+{% endif %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% if target.pk %}
+  {{ target }}
+  {% else %}
+  {% trans "New role" %}
+  {% endif %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+
+  <fieldset>
+    <legend>{% trans "Basic settings" %}</legend>
+
+    {% form_row form.name "col-md-3" "col-md-9" %}
+
+  </fieldset>
+
+  {% for form in perms_forms %}
+  {% include "misago/admin/permissions_table.html" %}
+  {% endfor %}
+
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}

+ 74 - 0
misago/templates/misago/admin/roles/list.html

@@ -0,0 +1,74 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:permissions:users:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New role" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th>{% trans "Role" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td class="item-name">
+  {{ item }}
+</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link role_id=item.id %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  <a href="{% url 'misago:admin:permissions:users:users' role_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Users with role" %}">
+    <span class="fa fa-users"></span>
+  </a>
+</td>
+<td class="row-action">
+  <a href="{% url 'misago:admin:permissions:users:edit' role_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+<td class="row-action">
+  <form action="{% url 'misago:admin:permissions:users:delete' role_id=item.id %}" method="post" class="delete-prompt">
+    <button class="btn btn-danger tooltip-top" title="{% trans "Delete" %}">
+      {% csrf_token %}
+      <span class="fa fa-times"></span>
+    </button>
+  </form>
+</td>
+{% endblock %}
+
+
+{% block emptylist %}
+<td colspan="{{ 4|add:extra_actions_len }}">
+  <p>{% trans "No user roles are currently defined." %}</p>
+</td>
+{% endblock emptylist %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('.delete-prompt').submit(function() {
+      var decision = confirm("{% trans "Are you sure you want to delete this role?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}

+ 90 - 0
misago/templates/misago/admin/users/ban.html

@@ -0,0 +1,90 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_avatars misago_capture misago_forms %}
+
+
+{% block title %}
+{% trans "Ban users" %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% trans "Ban users" %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>{% trans "Ban selected users:" %}</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<input type="hidden" name="action" value="ban">
+{% for user in users %}
+<input type="hidden" name="selected_items" value="{{ user.pk }}">
+{% endfor %}
+<table class="table table-condensed form-table">
+  {% for user in users %}
+  <tr>
+    <td style="width: 1%;">
+      <a href="{{ user.get_absolute_url }}">
+        <img src="{{ user|avatar:24 }}" alt="{% trans "Avatar" %}" width="24" height="24">
+      </a>
+    </td>
+    <td class="item-name">
+      <a href="{{ user.get_absolute_url }}">{{ user }}</a>
+    </td>
+    <td>
+      {{ user.email }}
+    </td>
+    <td>
+      {{ user.joined_from_ip }}
+    </td>
+  </tr>
+  {% endfor %}
+</table>
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Ban settings" %}</legend>
+
+    {% form_row form.ban_type label_class field_class %}
+    {% form_row form.expires_on label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Messages" %}</legend>
+
+    {% form_row form.user_message label_class field_class %}
+    {% form_row form.staff_message label_class field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer %}
+<button class="btn btn-primary" name="finalize">{% trans "Set bans" %}</button>
+{% endblock %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('#id_valid_until').datetimepicker({
+      language: $('html').attr('lang'),
+      pickTime: false
+    });
+  });
+</script>
+{% endblock %}

+ 157 - 0
misago/templates/misago/admin/users/delete.html

@@ -0,0 +1,157 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_avatars misago_capture misago_forms %}
+
+
+{% block title %}
+{% trans "Delete users with content" %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% trans "Delete users with content" %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% trans "Deleting users..." %}
+</h1>
+{% endblock %}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% for user in users %}
+  <fieldset class="user queued">
+    <legend>{{ user.username }}</legend>
+
+    <div class="extra-padding">
+      <ul class="list-unstyled">
+        <li class="step queued" data-url="{% url 'misago:admin:users:accounts:delete_threads' user_id=user.id %}" data-total="{{ user.thread_set.count }}">
+          <span class="fa fa-clock-o fa-fw text-muted"></span>
+          {% trans "Threads" %}: <strong><em class="text-muted">{% trans "queued" %}</em></strong>
+        </li>
+        <li class="step queued" data-url="{% url 'misago:admin:users:accounts:delete_posts' user_id=user.id %}" data-total="{{ user.post_set.count }}">
+          <span class="fa fa-clock-o fa-fw text-muted"></span>
+          {% trans "Posts" %}: <strong><em class="text-muted">{% trans "queued" %}</em></strong>
+        </li>
+        <li class="step queued" data-url="{% url 'misago:admin:users:accounts:delete_account' user_id=user.id %}">
+          <span class="fa fa-clock-o fa-fw text-muted"></span>
+          {% trans "Account" %}: <strong><em class="text-muted">{% trans "queued" %}</em></strong>
+        </li>
+      </ul>
+    </div>
+
+  </fieldset>
+  {% endfor %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer %}{% endblock form-footer %}
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+
+    DeletionController = function($e, on_complete) {
+
+      this.lang_deleting = "{% trans "deleting..." %}";
+      this.done = "{% trans "done" %}";
+
+      this.$e = $e;
+      this.on_complete = on_complete;
+      this.form_data = $e.parents('form').serialize();
+
+      var _this = this;
+
+      this.step = function($step) {
+
+        var url = $step.data('url');
+        var total = $step.data('total');
+
+        var $icon = $step.find('.fa');
+        var $label = $step.find('strong');
+
+        var processed = 0;
+
+        $icon.attr('class', 'fa fa-cog fa-spin fa-fw text-danger');
+        $label.html(this.lang_deleting);
+
+        function query_server() {
+          $.post(url, _this.form_data, function(data) {
+
+            if (data.is_completed) {
+
+              $icon.attr('class', 'fa fa-check fa-fw text-success');
+              $label.html(_this.done);
+              $step.removeClass('queued');
+              _this.process();
+
+            } else {
+
+              if (total !== undefined && total > 0) {
+                processed += data.deleted_count;
+                progress = Math.round(processed * 100 / total);
+
+                if (progress > 100) {
+                  progress = 100;
+                }
+
+                $label.html(_this.lang_deleting + " " + progress + "%");
+              }
+              query_server();
+
+            }
+
+          });
+        }
+
+        query_server();
+
+      }
+
+      this.complete = function() {
+
+        this.$e.removeClass('queued');
+        on_complete();
+
+      }
+
+      this.process = function() {
+
+        var $step = this.$e.find('.step.queued').first();
+
+        if ($step.length) {
+          this.step($step);
+        } else {
+          this.complete();
+        }
+
+      }
+      this.process();
+
+    };
+
+    function delete_user() {
+
+      var $user = $('.user.queued').first();
+
+      if ($user.length) {
+        var controller = new DeletionController($user, delete_user);
+      } else {
+
+        var $form = $('.user').first().parents('form');
+        var $btn = $form.find('.btn-default');
+
+        $btn.text("{% trans "Return to list of users" %}");
+        $btn.attr('class', 'btn btn-success');
+
+      }
+
+    }
+    delete_user();
+
+  });
+</script>
+{% endblock %}

+ 93 - 0
misago/templates/misago/admin/users/edit.html

@@ -0,0 +1,93 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{{ target }} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{{ target }}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {{ target }}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Basic account settings" %}</legend>
+
+    {% form_row form.username label_class field_class %}
+
+    {% if 'rank' in form.fields %}
+    {% form_row form.rank label_class field_class %}
+    {% endif %}
+
+    {% form_row form.title label_class field_class %}
+    {% form_row form.roles label_class field_class %}
+
+    {% if 'staff_level' in form.fields %}
+    {% form_row form.staff_level label_class field_class %}
+    {% endif %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Sign-in credentials" %}</legend>
+
+    {% form_row form.email label_class field_class %}
+    {% form_row form.new_password label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Avatar" %}</legend>
+
+    {% form_row form.is_avatar_locked label_class field_class %}
+    {% form_row form.avatar_lock_user_message label_class field_class %}
+    {% form_row form.avatar_lock_staff_message label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Signature" %}</legend>
+
+    {% form_row form.signature label_class field_class %}
+    {% form_row form.is_signature_locked label_class field_class %}
+    {% form_row form.signature_lock_user_message label_class field_class %}
+    {% form_row form.signature_lock_staff_message label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Forum options" %}</legend>
+
+    {% form_row form.is_hiding_presence label_class field_class %}
+    {% form_row form.limits_private_thread_invites_to label_class field_class %}
+    {% form_row form.timezone label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Automatic subscription preferences" %}</legend>
+
+    {% form_row form.subscribe_to_started_threads label_class field_class %}
+    {% form_row form.subscribe_to_replied_threads label_class field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}

+ 124 - 0
misago/templates/misago/admin/users/list.html

@@ -0,0 +1,124 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n misago_avatars misago_forms %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:users:accounts:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New user" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th style="width: 1%;">&nbsp;</th>
+<th>{% trans "User" %}</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 200px;">{% trans "E-mail" %}</th>
+<th style="width: 150px;">{% trans "Rank" %}</th>
+<th style="width: 200px;">{% trans "Joined" %}</th>
+<th style="width: 128px;">{% trans "Posts" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td>
+  <a href="{{ item.get_absolute_url }}">
+    <img src="{{ item|avatar:24 }}" alt="{% trans "Avatar" %}" width="24" height="24">
+  </a>
+</td>
+<td class="item-name {% if item.requires_activation %}text-muted{% endif %}">
+  <a href="{{ item.get_absolute_url }}">{{ item }}</a>
+</td>
+<td class="lead text-muted">
+  {% if item.requires_activation_by_admin %}
+  <span class="fa fa-eye tooltip-top" title="{% trans "Requires activation by administrator" %}"></span>
+  {% elif item.requires_activation_by_user %}
+  <span class="fa fa-ticket tooltip-top" title="{% trans "Has to activate account" %}"></span>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td class="lead text-muted">
+  {% if item.is_superuser %}
+  <span class="fa fa-star tooltip-top" title="{% trans "Super administrator" %}"></span>
+  {% elif item.is_staff %}
+  <span class="fa fa-star-half-o tooltip-top" title="{% trans "Administrator" %}"></span>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td>
+  <a href="mailto:{{ item.email }}">{{ item.email }}</a>
+</td>
+<td>
+  {{ item.rank }}
+</td>
+<td>
+  <abbr class="tooltip-top dynamic time-ago" title="{{ item.joined_on }}" data-timestamp="{{ item.joined_on|date:"c" }}">
+    {{ item.joined_on|date }}
+  </abbr>
+</td>
+<td>
+  {{ item.posts }}
+</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link user_id=item.id %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  <a href="{% url 'misago:admin:users:accounts:edit' user_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit user" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+{% endblock table-row %}
+
+
+{% block emptylist %}
+<td colspan="{{ 11|add:extra_actions_len }}">
+  <p>{% trans "No users matching search criteria have been found." %}</p>
+</td>
+{% endblock emptylist %}
+
+
+{% block modal-title %}
+{% trans "Search users" %}
+{% endblock modal-title %}
+
+
+{% block modal-body %}
+<div class="row">
+  <div class="col-md-6">
+    {% form_row search_form.username %}
+  </div>
+  <div class="col-md-6">
+    {% form_row search_form.email %}
+  </div>
+</div>
+<div class="row">
+  <div class="col-md-6">
+    {% form_row search_form.rank %}
+  </div>
+  <div class="col-md-6">
+    {% form_row search_form.role %}
+  </div>
+</div>
+<div class="row">
+  <div class="col-md-6">
+    {% form_row search_form.inactive %}
+  </div>
+  <div class="col-md-6">
+    {% form_row search_form.is_staff %}
+  </div>
+</div>
+{% endblock modal-body %}

+ 66 - 0
misago/templates/misago/admin/users/new.html

@@ -0,0 +1,66 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% trans "New user" %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% trans "New user" %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% trans "New user" %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Basic account settings" %}</legend>
+
+    {% form_row form.username label_class field_class %}
+
+    {% if 'rank' in form.fields %}
+    {% form_row form.rank label_class field_class %}
+    {% endif %}
+
+    {% form_row form.title label_class field_class %}
+    {% form_row form.roles label_class field_class %}
+
+    {% if 'staff_level' in form.fields %}
+    {% form_row form.staff_level label_class field_class %}
+    {% endif %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Sign-in credentials" %}</legend>
+
+    {% form_row form.email label_class field_class %}
+    {% form_row form.new_password label_class field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}
+
+
+{% block form-footer %}
+<button class="btn btn-primary">{% trans "Save user" %}</button>
+{% endblock form-footer %}

+ 63 - 0
misago/templates/misago/admin/warnings/form.html

@@ -0,0 +1,63 @@
+{% extends "misago/admin/generic/form.html" %}
+{% load i18n misago_forms %}
+
+
+{% block title %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New warning level" %}
+{% endif %} | {{ active_link.name }} | {{ block.super }}
+{% endblock title %}
+
+
+{% block page-target %}
+{% if target.pk %}
+{{ target }}
+{% else %}
+{% trans "New warning level" %}
+{% endif %}
+{% endblock page-target %}
+
+
+{% block form-header %}
+<h1>
+  {% if target.pk %}
+  {{ target }}
+  {% else %}
+  {% trans "New warning level" %}
+  {% endif %}
+</h1>
+{% endblock %}
+
+
+{% block form-extra %}
+class="form-horizontal"
+{% endblock form-extra%}
+
+
+{% block form-body %}
+<div class="form-body">
+  {% with label_class="col-md-3" field_class="col-md-9" %}
+  <fieldset>
+    <legend>{% trans "Basic options" %}</legend>
+
+    {% form_row form.name label_class field_class %}
+    {% form_row form.length_in_minutes label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Restrictions" %}</legend>
+
+    {% form_row form.restricts_posting_replies label_class field_class %}
+    {% form_row form.restricts_posting_threads label_class field_class %}
+
+  </fieldset>
+  {% endwith %}
+</div>
+{% endblock form-body %}
+
+
+{% block form-footer-class %}
+col-md-offset-3
+{% endblock form-footer-class %}

+ 134 - 0
misago/templates/misago/admin/warnings/list.html

@@ -0,0 +1,134 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n %}
+
+
+{% block page-actions %}
+<div class="page-actions">
+  <a href="{% url 'misago:admin:users:warnings:new' %}" class="btn btn-success">
+    <span class="fa fa-plus-circle"></span>
+    {% trans "New level" %}
+  </a>
+</div>
+{% endblock %}
+
+
+{% block table-header %}
+<th>{% trans "Warning level" %}</th>
+<th style="width: 20%">{% trans "Length" %}</th>
+<th style="width: 20%;">{% trans "Replying" %}</th>
+<th style="width: 20%;">{% trans "Starting threads" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td class="item-name">
+  #{{ forloop.counter }} {{ item }}
+</td>
+<td>{{ item.length }}</td>
+<td>
+  {% if item.restricts_posting_replies == 0 %}
+  <div class="text-success">
+    <span class="fa fa-check-circle"></span>
+    {% trans "Not restricted" %}
+  </div>
+  {% elif item.restricts_posting_replies == 1 %}
+  <div class="text-warning">
+    <span class="fa fa-exclamation-circle"></span>
+    {% trans "Moderated" %}
+  </div>
+  {% else %}
+  <div class="text-danger">
+    <span class="fa fa-times-circle"></span>
+    {% trans "Forbidden" %}
+  </div>
+  {% endif %}
+</td>
+<td>
+  {% if item.restricts_posting_threads == 0 %}
+  <div class="text-success">
+    <span class="fa fa-check-circle"></span>
+    {% trans "Not restricted" %}
+  </div>
+  {% elif item.restricts_posting_threads == 1 %}
+  <div class="text-warning">
+    <span class="fa fa-exclamation-circle"></span>
+    {% trans "Moderated" %}
+  </div>
+  {% else %}
+  <div class="text-danger">
+    <span class="fa fa-times-circle"></span>
+    {% trans "Forbidden" %}
+  </div>
+  {% endif %}
+</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link rank_id=item.id %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  {% if not forloop.last %}
+  <form action="{% url 'misago:admin:users:warnings:down' warning_id=item.id %}" method="post">
+    <button class="btn btn-default tooltip-top" title="{% trans "Move down" %}">
+      {% csrf_token %}
+      <span class="fa fa-chevron-down"></span>
+    </button>
+  </form>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td class="row-action">
+  {% if not forloop.first %}
+  <form action="{% url 'misago:admin:users:warnings:up' warning_id=item.id %}" method="post">
+    <button class="btn btn-default tooltip-top" title="{% trans "Move up" %}">
+      {% csrf_token %}
+      <span class="fa fa-chevron-up"></span>
+    </button>
+  </form>
+  {% else %}
+  &nbsp;
+  {% endif %}
+</td>
+<td class="row-action">
+  <a href="{% url 'misago:admin:users:warnings:edit' warning_id=item.id %}" class="btn btn-primary tooltip-top" title="{% trans "Edit" %}">
+    <span class="fa fa-pencil"></span>
+  </a>
+</td>
+<td class="row-action">
+  <form action="{% url 'misago:admin:users:warnings:delete' warning_id=item.id %}" method="post" class="delete-prompt">
+    <button class="btn btn-danger tooltip-top" title="{% trans "Delete" %}">
+      {% csrf_token %}
+      <span class="fa fa-times"></span>
+    </button>
+  </form>
+</td>
+{% endblock %}
+
+
+{% block emptylist %}
+<td colspan="{{ 8|add:extra_actions_len }}">
+  <p>{% trans "No warning levels are currently defined." %}</p>
+</td>
+{% endblock emptylist %}
+
+
+{% block javascripts %}
+<script type="text/javascript">
+  $(function() {
+    $('.delete-prompt').submit(function() {
+      var decision = confirm("{% trans "Are you sure you want to delete this warning level?" %}");
+      return decision;
+    });
+  });
+</script>
+{% endblock %}

+ 18 - 0
misago/templates/misago/emails/activation/by_admin.html

@@ -0,0 +1,18 @@
+{% extends "misago/emails/base.html" %}
+{% load i18n misago_capture %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, your account has been activated by forum administrator.
+{% endblocktrans %}
+<br>
+<br>
+{% capture trimmed as login_link %}
+<a href="{{ SITE_ADDRESS }}{% url LOGIN_URL %}">{% trans "this form" %}</a>
+{% endcapture %}
+{% blocktrans trimmed with login_form=login_link|safe %}
+You can now sign in to it using {{ login_form }}.
+{% endblocktrans %}
+<br>
+{% endblock content %}

+ 14 - 0
misago/templates/misago/emails/activation/by_admin.txt

@@ -0,0 +1,14 @@
+{% extends "misago/emails/base.txt" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, your account has been activated by forum administrator.
+{% endblocktrans %}
+
+{% blocktrans trimmed %}
+You can now sign in to it using the form below:
+{% endblocktrans %}
+{{ SITE_ADDRESS }}{% url LOGIN_URL %}
+{% endblock content %}

+ 13 - 0
misago/templates/misago/emails/activation/by_user.html

@@ -0,0 +1,13 @@
+{% extends "misago/emails/base.html" %}
+{% load i18n misago_capture %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, to activate your account click the below link:
+{% endblocktrans %}
+<br>
+<br>
+<a href="{{ SITE_ADDRESS }}{% url 'misago:activate_by_token' user_id=recipient.id token=activation_token %}">{% trans "Activate my account!" %}</a>
+<br>
+{% endblock content %}

+ 10 - 0
misago/templates/misago/emails/activation/by_user.txt

@@ -0,0 +1,10 @@
+{% extends "misago/emails/base.txt" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, to activate your account click the below link:
+{% endblocktrans %}
+{{ SITE_ADDRESS }}{% url 'misago:activate_by_token' user_id=recipient.id token=activation_token %}"
+{% endblock content %}

+ 90 - 0
misago/templates/misago/emails/base.html

@@ -0,0 +1,90 @@
+{% load misago_avatars %}
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="{{ LANGUAGE_CODE }}">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <meta name="viewport" content="initial-scale=1.0">    <!-- So that mobile webkit will display zoomed in -->
+    <meta name="format-detection" content="telephone=no"> <!-- disable auto telephone linking in iOS -->
+
+    <style type="text/css">
+
+        /* Resets: see reset.css for details */
+        .ReadMsgBody { width: 100%; background-color: #eff0f1;}
+        .ExternalClass {width: 100%; background-color: #eff0f1;}
+        .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height:100%;}
+        body {-webkit-text-size-adjust:none; -ms-text-size-adjust:none;}
+        body {margin:0; padding:0;}
+        table {border-spacing:0;}
+        table td {border-collapse:collapse;}
+        .yshortcuts a {border-bottom: none !important;}
+
+
+        /* Constrain email width for small screens */
+        @media screen and (max-width: 600px) {
+            table[class="container"] {
+                width: 95% !important;
+            }
+        }
+
+        /* Give content more room on mobile */
+        @media screen and (max-width: 480px) {
+            td[class="container-padding"] {
+                padding-left: 12px !important;
+                padding-right: 12px !important;
+            }
+        }
+
+    </style>
+</head>
+<body style="margin:0; padding:10px 0;" bgcolor="#eff0f1" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
+
+<br>
+
+<!-- 100% wrapper (grey background) -->
+<table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0" bgcolor="#eff0f1">
+  <tr>
+    <td align="center" valign="top" bgcolor="#eff0f1" style="background-color: #eff0f1;">
+
+      <!-- 600px container (white background) -->
+      <table border="0" width="600" cellpadding="0" cellspacing="0" class="container" bgcolor="#ffffff">
+        <tr>
+          <td class="container-padding" bgcolor="#ffffff" style="background-color: #ffffff; border: 1px solid #dde0e2; padding-left: 30px; padding-right: 30px; font-size: 13px; line-height: 20px; font-family: Helvetica, sans-serif; color: #333; padding-top: 4px;" align="left">
+            <br>
+
+            <!-- ### BEGIN CONTENT ### -->
+
+              <table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td valign="middle" style="font-size: 28px; line-height: 24px; color: #555555;">{{ misago_settings.forum_name }}</td>
+                  <td align="center" valign="middle" width="30"><img src="{{ SITE_PROTOCOL }}:{{ recipient|avatar:32 }}" width="32" height="32" style="border-radius: 3px;" alt=""></td>
+                </tr>
+              </table>
+            <br>
+
+            <div style="font-weight: bold; font-size: 18px; line-height: 24px; color: #333; border-top: 1px solid #ddd;"><br>{% block title %}{{ subject }}{% endblock %}</div>
+            <br>
+
+            {% block content %}{% endblock content %}
+
+            <br>
+            <div style="border-top: 1px solid #ddd; color: #666; font-size: 12px; line-height: 18px;">
+              {% if misago_settings.email_footer %}<br>{{ misago_settings.email_footer }}{% endif %}
+              <br><a href="{{ SITE_ADDRESS }}" style="color: #888; text-decoration: underline;">Sent from {{ SITE_HOST }}</a>
+            </div>
+
+            <!-- ### END CONTENT ### -->
+            <br>
+
+          </td>
+        </tr>
+      </table>
+      <!--/600px container -->
+
+    </td>
+  </tr>
+</table>
+<!--/100% wrapper-->
+<br>
+<br>
+</body>
+</html>

+ 11 - 0
misago/templates/misago/emails/base.txt

@@ -0,0 +1,11 @@
+{{ misago_settings.forum_name }}
+================================================
+
+{% block title %}{{ subject }}{% endblock %}
+
+{% block content %}{% endblock content %}
+
+
+------------------------------------------------
+{% if misago_settings.email_footer %}{{ misago_settings.email_footer }}{% endif %}
+Sent from {{ SITE_ADDRESS }}

+ 18 - 0
misago/templates/misago/emails/change_email_password.html

@@ -0,0 +1,18 @@
+{% extends "misago/emails/base.html" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, you are receiving this message because you have made changes in your account email and password.
+{% endblocktrans %}
+<br>
+<br>
+{% blocktrans trimmed %}
+To confirm those changes, click the link below:
+{% endblocktrans %}
+<br>
+<br>
+<a href="{{ SITE_ADDRESS }}{% url 'misago:usercp_confirm_email_password_change' token=credentials_token %}">{% trans "Save changes" %}</a>
+<br>
+{% endblock content %}

+ 14 - 0
misago/templates/misago/emails/change_email_password.txt

@@ -0,0 +1,14 @@
+{% extends "misago/emails/base.txt" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, you are receiving this message because you have made changes in your account email and password.
+{% endblocktrans %}
+
+{% blocktrans trimmed %}
+To confirm those changes, click the link below:
+{% endblocktrans %}
+{{ SITE_ADDRESS }}{% url 'misago:usercp_confirm_email_password_change' token=credentials_token %}
+{% endblock content %}

+ 18 - 0
misago/templates/misago/emails/change_password_form_link.html

@@ -0,0 +1,18 @@
+{% extends "misago/emails/base.html" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, you are receiving this message because you want to change forgotten password for your forum account.
+{% endblocktrans %}
+<br>
+<br>
+{% blocktrans trimmed %}
+To change your account password click the link below:
+{% endblocktrans %}
+<br>
+<br>
+<a href="{{ SITE_ADDRESS }}{% url 'misago:reset_password_form' user_id=recipient.id token=confirmation_token %}">{% trans "Set new password" %}</a>
+<br>
+{% endblock content %}

+ 14 - 0
misago/templates/misago/emails/change_password_form_link.txt

@@ -0,0 +1,14 @@
+{% extends "misago/emails/base.txt" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, you are receiving this message because you want to change forgotten password for your forum account.
+{% endblocktrans %}
+
+{% blocktrans trimmed %}
+To change your account password click the link below:
+{% endblocktrans %}
+{{ SITE_ADDRESS }}{% url 'misago:reset_password_form' user_id=recipient.id token=confirmation_token %}
+{% endblock content %}

+ 21 - 0
misago/templates/misago/emails/privatethread/added.html

@@ -0,0 +1,21 @@
+{% extends "misago/emails/base.html" %}
+{% load i18n misago_capture %}
+
+
+{% block content %}
+{% capture trimmed as thread_title %}
+<strong>{{ thread.title }}</strong>
+{% endcapture %}
+{% blocktrans trimmed with user=recipient.username sender=sender.username thread=thread_title %}
+{{ user }}, you are receiving this message because {{ sender }} has invited you to participate in private thread {{ thread }}.
+{% endblocktrans %}
+<br>
+<br>
+{% blocktrans trimmed %}
+To go to this thread click the link below:
+{% endblocktrans %}
+<br>
+<br>
+<a href="{{ SITE_ADDRESS }}{{ thread.get_absolute_url }}">{{ thread.title }}</a>
+<br>
+{% endblock content %}

+ 14 - 0
misago/templates/misago/emails/privatethread/added.txt

@@ -0,0 +1,14 @@
+{% extends "misago/emails/base.txt" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient.username sender=sender.username thread=thread.title %}
+{{ user }}, you are receiving this message because {{ sender }} has invited you to participate in private thread "{{ thread }}".
+{% endblocktrans %}
+
+{% blocktrans trimmed %}
+To go to this thread click the link below:
+{% endblocktrans %}
+{{ SITE_ADDRESS }}{{ thread.get_absolute_url }}
+{% endblock content %}

+ 25 - 0
misago/templates/misago/emails/register/complete.html

@@ -0,0 +1,25 @@
+{% extends "misago/emails/base.html" %}
+{% load i18n misago_capture %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, thank you for joining us!
+{% endblocktrans %}
+<br>
+<br>
+{% block activation-message %}
+{% blocktrans trimmed %}
+You may now join discussion on our forums. Why not spend a minute or two to have a look around and share your opinions and knowledge with rest of community?
+{% endblocktrans %}
+<br>
+<br>
+{% capture trimmed as login_link %}
+<a href="{{ SITE_ADDRESS }}{% url LOGIN_URL %}">{% trans "this form" %}</a>
+{% endcapture %}
+{% blocktrans trimmed with login_form=login_link|safe %}
+You can always sign in to your account using {{ login_form }}.
+{% endblocktrans %}
+<br>
+{% endblock activation-message %}
+{% endblock content %}

+ 18 - 0
misago/templates/misago/emails/register/complete.txt

@@ -0,0 +1,18 @@
+{% extends "misago/emails/base.txt" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, thank you for joining us!
+{% endblocktrans %}
+
+{% blocktrans trimmed %}
+You may now join discussion on our forums. Why not spend a minute or two to have a look around and share your opinions and knowledge with rest of community?
+{% endblocktrans %}
+
+{% blocktrans trimmed %}
+You can always sign in to your account using the form below:
+{% endblocktrans %}
+{{ SITE_ADDRESS }}{% url LOGIN_URL %}
+{% endblock content %}

+ 38 - 0
misago/templates/misago/emails/register/inactive.html

@@ -0,0 +1,38 @@
+{% extends "misago/emails/register/complete.html" %}
+{% load i18n misago_capture %}
+
+
+{% block activation-message %}
+{% if activation_by_admin %}
+  {% blocktrans trimmed %}
+  Before you will be able to join discussion on our forums, one of our administrators will have to activate your account.
+  {% endblocktrans %}
+  <br>
+  <br>
+  {% blocktrans trimmed %}
+  This may take a while, but you will receive e-mail with notification once it happens.
+  {% endblocktrans %}
+  <br>
+  <br>
+  {% blocktrans trimmed %}
+  Thank you for your patience and see you soon!
+  {% endblocktrans %}
+  <br>
+{% elif activation_by_user %}
+  {% blocktrans trimmed %}
+  Before you will be able to join discussion on our forums, you have to activate your account. To do so, simply click the link below:
+  {% endblocktrans %}
+  <br>
+  <br>
+  <a href="{{ SITE_ADDRESS }}{% url 'misago:activate_by_token' user_id=recipient.id token=activation_token %}">{% trans "Activate my account!" %}</a>
+  <br>
+  <br>
+  {% capture trimmed as login_link %}
+  <a href="{{ SITE_ADDRESS }}{% url LOGIN_URL %}">{% trans "this form" %}</a>
+  {% endcapture %}
+  {% blocktrans trimmed with login_form=login_link|safe %}
+  Once your account is activated, you can always sign in to it using {{ login_form }}.
+  {% endblocktrans %}
+  <br>
+{% endif %}
+{% endblock activation-message %}

+ 35 - 0
misago/templates/misago/emails/register/inactive.txt

@@ -0,0 +1,35 @@
+{% extends "misago/emails/base.txt" %}
+{% load i18n %}
+
+
+{% block content %}
+{% blocktrans trimmed with user=recipient %}
+{{ user }}, thank you for joining us!
+{% endblocktrans %}
+{% if activation_by_admin %}
+  {% blocktrans trimmed %}
+  Before you will be able to join discussion on our forums, one of our administrators will have to activate your account.
+  {% endblocktrans %}
+
+
+  {% blocktrans trimmed %}
+  This may take a while, but you will receive e-mail with notification once it happens.
+  {% endblocktrans %}
+
+
+  {% blocktrans trimmed %}
+  Thank you for your patience and see you soon!
+  {% endblocktrans %}
+
+{% elif activation_by_user %}
+  {% blocktrans trimmed %}
+  Before you will be able to join discussion on our forums, you have to activate your account. To do so, simply click the link below:
+  {% endblocktrans %}
+  {{ SITE_ADDRESS }}{% url 'misago:activate_by_token' user_id=recipient.id token=activation_token %}"
+
+  {% blocktrans trimmed with login_form=login_link|safe %}
+  Once your account is activated, you can always sign in to it using the form velow:
+  {% endblocktrans %}
+  {{ SITE_ADDRESS }}{% url LOGIN_URL %}
+{% endif %}
+{% endblock content %}

+ 3 - 1
misago/templates/misago/index.html

@@ -15,5 +15,7 @@
 
 
 
 
 {% block content %}
 {% block content %}
-<p>If you see this, ember failed to render application template.</p>
+<div class="container">
+  <p class="lead">This is Django-rendered forum index template.</p>
+</div>
 {% endblock content %}
 {% endblock content %}