laterite-admin 0.9.13

Laterite CMF admin surface: the Axum router, session middleware, and login shell
Documentation
{% extends "base.html" %}
{% block title %}{{ shell.t("Preferences") }} - {{ shell.brand }}{% endblock %}
{% block content %}
<div class="lat-toolbar"><h1>{{ shell.t("Preferences") }}</h1></div>
<div class="lat-card lat-card--form">
  <form method="post" action="{{ shell.base }}/preferences" data-lat-widget="form">
    {% include "_csrf.html" %}
    <div class="lat-field">
      <label class="lat-field__label" for="timezone">{{ shell.t("Display timezone") }}</label>
      <select class="lat-input lat-select" id="timezone" name="timezone">
        <option value=""{% if inherits %} selected{% endif %}>{{ shell.t("Use the deployment default") }} ({{ default_tz }})</option>
        {% for zone in zones %}<option value="{{ zone.name }}"{% if zone.selected %} selected{% endif %}>{{ zone.name }}</option>{% endfor %}
      </select>
      <p class="lat-help">Timestamps currently render in {{ effective_tz }}. Storage is always UTC; this only changes how dates are shown to you.</p>
    </div>
    <div class="lat-field">
      <label class="lat-field__label" for="locale">{{ shell.t("Language") }}</label>
      <select class="lat-input lat-select" id="locale" name="locale">
        <option value=""{% if inherits_locale %} selected{% endif %}>{{ shell.t("Use the deployment default") }} ({{ default_locale }})</option>
        {% for locale in locales %}<option value="{{ locale.code }}"{% if locale.selected %} selected{% endif %}>{{ locale.name }}</option>{% endfor %}
      </select>
      <p class="lat-help">{{ shell.t("The admin renders in this language. It only changes the interface, not your content.") }}</p>
    </div>
    <div class="lat-actions">
      <button class="lat-btn lat-btn--primary" type="submit">{{ shell.t("Save") }}</button>
    </div>
  </form>
</div>

<div class="lat-toolbar lat-toolbar--section" id="password"><h2>{{ shell.t("Password") }}</h2></div>
<div class="lat-card lat-card--form">
  {% if must_change %}<div class="lat-alert" data-lat-persist>{{ shell.t("This password is temporary. Set one of your own to continue.") }}</div>{% endif %}
  <dl class="lat-facts">
    <div><dt>{{ shell.t("Last changed") }}</dt><dd>{% if let Some(at) = password_changed %}{{ at }}{% else %}{{ shell.t("Not recorded") }}{% endif %}</dd></div>
  </dl>
  <form method="post" action="{{ shell.base }}/preferences/password" data-lat-widget="form">
    {% include "_csrf.html" %}
    <div class="lat-field">
      <label class="lat-field__label" for="current_password">{{ shell.t("Current password") }}</label>
      <div class="lat-input-group lat-reveal"><input class="lat-input" type="password" id="current_password" name="current_password" autocomplete="current-password" required><button type="button" class="lat-input-group__btn lat-reveal__btn" data-lat-widget="reveal" aria-label='{{ shell.t("Show password") }}' aria-pressed="false" hidden></button></div>
    </div>
    <div class="lat-field">
      <label class="lat-field__label" for="new_password">{{ shell.t("New password") }}</label>
      <div class="lat-input-group lat-reveal"><input class="lat-input" type="password" id="new_password" name="new_password" autocomplete="new-password" minlength="{{ min_password }}" required><button type="button" class="lat-input-group__btn lat-reveal__btn" data-lat-widget="reveal" aria-label='{{ shell.t("Show password") }}' aria-pressed="false" hidden></button></div>
      <p class="lat-help">{{ shell.tf("At least {n} characters. Every other device is signed out.", [("n", min_password)]) }}</p>
    </div>
    <div class="lat-field">
      <label class="lat-field__label" for="confirm_password">{{ shell.t("Confirm new password") }}</label>
      <div class="lat-input-group lat-reveal"><input class="lat-input" type="password" id="confirm_password" name="confirm_password" autocomplete="new-password" minlength="{{ min_password }}" required><button type="button" class="lat-input-group__btn lat-reveal__btn" data-lat-widget="reveal" aria-label='{{ shell.t("Show password") }}' aria-pressed="false" hidden></button></div>
    </div>
    <div class="lat-actions">
      <button class="lat-btn lat-btn--primary" type="submit">{{ shell.t("Change password") }}</button>
    </div>
  </form>
</div>

<div class="lat-toolbar lat-toolbar--section"><h2>{{ shell.t("Signed-in devices") }}</h2></div>
<p class="lat-help lat-sectionintro">{{ shell.t("Every browser currently signed in to this account. Signing one out ends it immediately.") }}</p>
<div class="lat-tablewrap">
  <table class="lat-table">
    <thead>
      <tr>
        <th>{{ shell.t("Device") }}</th>
        <th>{{ shell.t("Signed in") }}</th>
        <th>{{ shell.t("Last active") }}</th>
        <th>{{ shell.t("Expires") }}</th>
        <th></th>
      </tr>
    </thead>
    <tbody>
      {% for item in sessions %}
      <tr>
        <td>
          {{ item.device }}{% if item.current %} <span class="lat-badge">{{ shell.t("This device") }}</span>{% endif %}
          {% if !item.ip_address.is_empty() %}<p class="lat-help">{{ item.ip_address }}</p>{% endif %}
        </td>
        <td>{{ item.started }}</td>
        <td>{{ item.last_seen }}</td>
        <td>{{ item.expires }}</td>
        <td class="lat-table__actions">
          {% if !item.current %}
          <form method="post" action="{{ shell.base }}/preferences/sessions/revoke">
            {% include "_csrf.html" %}
            <input type="hidden" name="id" value="{{ item.id }}">
            <button class="lat-btn lat-btn--danger" type="submit">{{ shell.t("Sign out") }}</button>
          </form>
          {% endif %}
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</div>
{% if sessions.len() > 1 %}
<form method="post" action="{{ shell.base }}/preferences/sessions/revoke-others">
  {% include "_csrf.html" %}
  <div class="lat-actions">
    <button class="lat-btn lat-btn--danger" type="submit">{{ shell.t("Sign out every other device") }}</button>
  </div>
</form>
{% endif %}
{% if !items.is_empty() %}
<div class="lat-toolbar lat-toolbar--section"><h2>{{ shell.t("More") }}</h2></div>
<div class="lat-card">
  <ul class="lat-palette__list lat-palette__list--page">
    {% for item in items %}<li><a class="lat-palette__hit" href="{{ item.href }}"><span class="lat-palette__label">{{ item.label }}</span>{% if !item.description.is_empty() %}<span class="lat-palette__hint">{{ item.description }}</span>{% endif %}</a></li>{% endfor %}
  </ul>
</div>
{% endif %}
<div class="lat-toolbar lat-toolbar--section"><h2>{{ shell.t("Menu") }}</h2></div>
<div class="lat-card lat-card--form">
  <p class="lat-note">{{ shell.t("Drag the tabs in the top bar into the order you want; it follows you to every device.") }}</p>
  <form method="post" action="{{ shell.base }}/preferences/menu">
    {% include "_csrf.html" %}
    <input type="hidden" name="order" value="">
    <div class="lat-actions">
      <button class="lat-btn lat-btn--secondary" type="submit">{{ shell.t("Reset the menu order") }}</button>
    </div>
  </form>
</div>
{% endblock %}