{% extends "controlpanel/base.html" %} {% load lucide ui %} {% block panel_title %}Features{% endblock panel_title %} {% block breadcrumb %} features | {{ flags|length }} flag{{ flags|length|pluralize }} | {{ switches|length }} switch{{ switches|length|pluralize }} | {{ competitions|length }} competition{{ competitions|length|pluralize }} {% endblock breadcrumb %} {% block actions %} {% endblock actions %} {% block panel %} {% url 'controlpanel:flag_create' as flag_create_url %} {% include "controlpanel/_modal_form.html" with modal_id="flag_create_modal" title="New feature" form=flag_form action_url=flag_create_url submit_label="Create" submit_icon="plus" %} {% url 'controlpanel:competition_create' as competition_create_url %} {% include "controlpanel/_modal_form.html" with modal_id="competition_create_modal" title="New competition" form=competition_form action_url=competition_create_url submit_label="Create" submit_icon="plus" %} {% comment %} The lock-down. Clubs get a maintenance page, the scheduled jobs stand down, and the control panel and the auth screens stay open — otherwise you could not sign in to turn it back off. This is the single most safety-critical control in the panel, so the active state gets the full club/club-dark treatment, not just a badge. {% endcomment %}
{% if maintenance.is_active %}
{% lucide "lock" size=18 class="shrink-0 text-white" %} Maintenance mode — platform closed since {{ maintenance.started_at|date:"j M Y, H:i" }}{% if maintenance.started_by %} · {{ maintenance.started_by.email }}{% endif %}
{% else %}
{% lucide "wrench" size=18 class="shrink-0 text-muted" %} Maintenance mode platform open
{% endif %}
{% if maintenance.is_active %} {% if maintenance.message %}
Message shown to clubs
{{ maintenance.message }}
{% endif %}

Every club subdomain is serving a maintenance page and the scheduled jobs have stood down. The control panel and the sign-in screens stay open.

{% csrf_token %}
{% else %}

Closes every club subdomain and stands the scheduled jobs down. The control panel and the sign-in screens stay open.

{% csrf_token %}
{{ maintenance_form.message|daisy }} {{ maintenance_form.message.help_text }}
{% endif %}
{% lucide "flag" size=16 class="shrink-0 text-muted" %} Flags {{ flags|length }} flag{{ flags|length|pluralize }}

Flags are turned on per club. Setting Everyone to Yes or No overrides club targeting entirely.

{% for flag in flags %} {% empty %} {% endfor %}
Name Everyone Clubs Note
{{ flag.name }} {% if flag.everyone is True %} On for all {% elif flag.everyone is False %} Off everywhere {% else %} Per club {% endif %} {{ flag.clubs.count }} {{ flag.note|default:"—" }}
No features yet.
{% comment %} Dialogs live outside the table: may only contain elements. {% endcomment %} {% for flag in flags %} {% url 'controlpanel:flag_update' flag.pk as flag_update_url %} {% include "controlpanel/_modal_form.html" with modal_id=flag.pk|dom_id:"flag_edit_modal" title="Edit "|add:flag.name form=flag.edit_form action_url=flag_update_url submit_label="Save" submit_icon="check" %} {% endfor %}
{% lucide "power" size=16 class="shrink-0 text-muted" %} Switches {{ switches|length }} switch{{ switches|length|pluralize }}

Global on/off for the whole platform — kill-switches, maintenance, infra rollouts.

{% for switch in switches %} {% empty %} {% endfor %}
Name Note
{{ switch.name }} {{ switch.note|default:"—" }}
{% csrf_token %}
No switches yet — add one in the Django admin.
{% lucide "trophy" size=16 class="shrink-0 text-muted" %} Competitions {{ competitions|length }} competition{{ competitions|length|pluralize }}

Data sources a game's score/status can be fetched from — see events.services.competitions. A club only sees one in its event form once its feature flag is on for them.

{% for competition in competitions %} {% empty %} {% endfor %}
Name Sport Module Flag
{{ competition.name }} {{ competition.get_sport_type_display }} {{ competition.module }} {% if competition.flag %} {{ competition.flag.name }} {% else %} No flag — hidden everywhere {% endif %}
No competitions yet.
{% comment %} Dialogs live outside the table: may only contain elements. {% endcomment %} {% for competition in competitions %} {% url 'controlpanel:competition_update' competition.pk as competition_update_url %} {% include "controlpanel/_modal_form.html" with modal_id=competition.pk|dom_id:"competition_edit_modal" title="Edit "|add:competition.name form=competition.edit_form action_url=competition_update_url submit_label="Save" submit_icon="check" %} {% url 'controlpanel:competition_delete' competition.pk as competition_delete_url %} {% include "controlpanel/_confirm_modal.html" with modal_id=competition.pk|dom_id:"competition_delete_modal" title="Delete "|add:competition.name body="No club-visible data is lost — Event.competition matches by name, not a foreign key, so existing games simply stop offering a live-score fetch." action_url=competition_delete_url submit_label="Delete" %} {% endfor %}
{% endblock panel %}