{% extends "admin/_layout.html" %} {% from "_macros.html" import icon %} {% set section = "users" %} {% block title %}{{ target.name }} - Users - {{ brand.name }}{% endblock %} {% block heading %}{{ target.name }}{% endblock %} {% block admin_content %}

{{ icon("chevron-left", "icon--sm") }} All users · {{ target.email }}

{% if saved %}
{{ icon("check", "icon--sm") }} {{ saved }}
{% endif %}

{{ t("Account") }}

{{ t("An administrator bypasses every permission and every quota below.") }}

{{ t("Turning this off signs them out everywhere at once, rather than waiting for a cookie to expire.") }}

{# --- What they can actually do -------------------------------------------- #}

{{ t("What this account can do") }}

Read-only, and deliberately: every switch here is set somewhere else — in the baseline or in a named group — and a control on this page would be a third place to change one thing. What it adds is the {{ t("source") }}, which is the question the grids could not answer without opening every group by eye.

{% for section_name, defs in permission_groups.items() %}
{{ section_name }} {% for definition in defs %} {% set state = explained[definition.key] %}
{{ icon("check" if state.on else "x", "icon--sm") }} {{ definition.label }} {% if state.on %} from {{ state.source | join(", ") }} {% else %} {{ t("not granted") }} {% endif %}
{% endfor %}
{% endfor %}
{# --- Membership ----------------------------------------------------------- #}

{{ t("Groups") }}

{{ t("Edited from the group's own page. One control per value, so a save here cannot undo a save there.") }}

{% if target.groups %}
{% for group in target.groups %} {{ group.name }} {% endfor %}
{% else %}

{{ t("In no group. They get the baseline and nothing more.") }}

{% endif %}
{# --- Quotas and usage ----------------------------------------------------- #}

{{ t("This month") }}

{{ t("Counted from the first of the month, UTC. Recorded for every reply including one that was stopped or failed — an endpoint charges for tokens it generated whether or not anybody wanted them.") }}

{{ t("Tokens") }}
{{ "{:,}".format(usage.tokens) }} {% if limits.monthly_tokens %} of {{ "{:,}".format(limits.monthly_tokens) }}{% endif %} ({{ "{:,}".format(usage.prompt_tokens) }} prompt, {{ "{:,}".format(usage.completion_tokens) }} written)
{{ t("Replies") }}
{{ usage.replies }}
{{ t("Images") }}
{{ usage.images }} this month, {{ usage.images_today }} today {% if limits.images_per_day %} (limit {{ limits.images_per_day }} a day){% endif %}

{{ t("Limits in force") }}

Resolved across their groups by {{ t("maximum") }} — the union rule applied to numbers, so a second group can only ever grant more. Zero means no limit and wins outright, because a group saying “unlimited” must not count for less than one saying “a million”.

{% for key, label, description in limit_defs %}
{{ label }}
{% if limits[key] %}{{ "{:,}".format(limits[key]) }}{% else %}no limit{% endif %} {{ description }}
{% endfor %}
{# --- Models --------------------------------------------------------------- #}

{{ t("Models they can use") }}

{{ t("Model access is separate from permissions: a permission says what somebody may do, this says what they may do it with.") }}

{% if models %}
{% for model in models %} {{ model.label }} {% endfor %}
{% else %}

{{ t("None. They cannot start a chat at all.") }}

{% endif %}
{# --- Dangerous ------------------------------------------------------------ #}

{{ t("Password and removal") }}

{{ t("Signs them out everywhere. An administrator resetting a password usually means the account is compromised or the person has gone.") }}

{{ t("Their chats, folders and library go too, and every share naming them or naming anything of theirs.") }}

{% endblock %}