src/templates/users/edit.html \
src/templates/users/index.html \
src/templates/users/passwd.html \
+ src/templates/users/recently-joined.html \
src/templates/users/show.html \
src/templates/users/subscribe.html \
src/templates/users/subscribed.html \
{% if recently_registered %}
<section class="section">
<div class="container">
- <h4 class="title is-4">{{ _("Recently Joined") }}</h4>
+ <h4 class="title is-4">
+ <a href="/users/recently-joined">
+ {{ _("Recently Joined") }}
+ </a>
+ </h4>
{% module UsersList(recently_registered, show_created_at=True) %}
</div>
--- /dev/null
+{% extends "../base.html" %}
+
+{% block title %}{{ _("Users") }} - {{ _("Recently Joined") }}{% end block %}
+
+{% block container %}
+ <section class="hero is-dark">
+ <div class="hero-body">
+ <div class="container">
+ <nav class="breadcrumb" aria-label="breadcrumbs">
+ <ul>
+ <li>
+ <a href="/">
+ {{ _("Home") }}
+ </a>
+ </li>
+
+ <li>
+ <a href="/users">
+ {{ _("Users") }}
+ </a>
+ </li>
+
+ <li class="is-active">
+ <a href="#" aria-current="page">
+ {{ _("Recently Joined") }}
+ </a>
+ </li>
+ </ul>
+ </nav>
+
+ <h1 class="title">{{ _("Recently Joined Users") }}</h1>
+ </div>
+ </div>
+ </section>
+
+ <section class="section">
+ <div class="container">
+ <form method="POST" action="">
+ {% raw xsrf_form_html() %}
+
+ <table class="table is-fullwidth is-hover">
+ <thead>
+ <tr>
+ <th>
+ {{ _("Name") }}
+ </th>
+
+ <th>
+ {{ _("Username") }}
+ </th>
+
+ <th>
+ {{ _("Email") }}
+ </th>
+
+ <th>
+ {{ _("Country") }}
+ </th>
+
+ <th>
+ {{ _("Joined At") }}
+ </th>
+
+ <th>
+ {{ _("Delete?") }}
+ </th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for account in accounts %}
+ <tr>
+ {# Name #}
+ <th scope="row">
+ <a href="/users/{{ account.uid }}">
+ {{ account }}
+ </a>
+ </th>
+
+ {# Username #}
+ <td>
+ {{ account.uid }}
+ </td>
+
+ {# Email #}
+ <td>
+ {{ account.email }}
+ </td>
+
+ {# Country Code #}
+ <td>
+ {% if account.country_code %}
+ {{ format_country_name(account.country_code) }}
+ {% else %}
+ <span class="has-text-grey">
+ {{ _("N/A") }}
+ </span>
+ {% end %}
+ </td>
+
+ {# Joined At #}
+ <td>
+ {{ locale.format_date(account.created_at, shorter=True) }}
+ </td>
+
+ {# Delete? #}
+ <td>
+ <input type="checkbox" name="users" value="{{ account.uid }}"
+ {% if not account.can_be_deleted_by(current_user) %}disabled{% end %}>
+ </td>
+ </tr>
+ {% end %}
+ </tbody>
+ </table>
+
+ <button type="submit" class="button is-danger is-fullwidth">
+ {{ _("Delete") }}
+ </button>
+ </form>
+ </div>
+ </section>
+{% end block %}
# Users
(r"/users", users.IndexHandler),
+ (r"/users/recently\-joined", users.RecentlyJoinedHandler),
(r"/users/([a-z_][a-z0-9_-]{0,31})", users.ShowHandler),
(r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", users.AvatarHandler),
(r"/users/([a-z_][a-z0-9_-]{0,31})/delete", users.DeleteHandler),
self.render("users/index.html", q=q, results=results)
+class RecentlyJoinedHandler(base.BaseHandler):
+ @tornado.web.authenticated
+ def get(self):
+ # Only staff can view this page
+ if not self.current_user.is_staff():
+ raise tornado.web.HTTPError(403)
+
+ # Fetch the most recently 100 registered accounts
+ accounts = self.backend.accounts.get_recently_registered(limit=100)
+
+ self.render("users/recently-joined.html", accounts=accounts)
+
+ @tornado.web.authenticated
+ async def post(self):
+ # Only staff can view this page
+ if not self.current_user.is_staff():
+ raise tornado.web.HTTPError(403)
+
+ # Fetch all selected accounts
+ accounts = [
+ self.backend.accounts.get_by_uid(uid) for uid in self.get_arguments("users")
+ ]
+
+ # Filter out all accounts that could not be found
+ accounts = [
+ account for account in accounts if account
+ ]
+
+ # Filter out everything that cannot be deleted by this user
+ accounts = [
+ account for account in accounts if account.can_be_deleted_by(self.current_user)
+ ]
+
+ # Delete them all!
+ for account in accounts:
+ with self.db.transaction():
+ await account.delete(self.current_user)
+
+ self.redirect("/users/recently-joined")
+
+
class ShowHandler(base.AnalyticsMixin, base.BaseHandler):
@tornado.web.authenticated
async def get(self, uid):