1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/appsettings/templates/appsettings.html
catborise c0978419f2 feat(appsettings): the settings page with a group index, two columns and switches
The Settings page was one tall column of cards, a label column beside
every field and True/False chosen from a select. Now an index of the
groups stays beside the cards on a wide screen and wraps above them on
a phone; each group lays its fields out in two columns with the label
above; a True/False setting is a switch; each Save names its group.

A switch posts nothing when off, so a hidden False of the same name
comes first and a checked switch's True, posted last, wins: the view
and its was-KEY check stay as they are.
2026-10-31 18:10:05 +03:00

105 lines
6.3 KiB
HTML

{% extends "base.html" %}
{% load i18n %}
{% block title %}{% trans "Edit Settings" %}{% endblock title %}
{% block page_heading %}{% trans "Edit Settings" %}{% endblock page_heading %}
{% block style %}
<style>
/* a group's card stops below the sticky navbar; the group index stays in view */
.settings-group { scroll-margin-top: 5rem; }
@media (min-width: 992px) {
.settings-index { position: sticky; top: 5rem; }
}
</style>
{% endblock style %}
{% block content %}
<div class="row g-4">
<div class="col-lg-3">
<nav class="settings-index" aria-label="{% trans 'Settings groups' %}">
<div class="nav nav-pills flex-wrap flex-lg-column gap-1">
<a class="nav-link" href="#appearance">{% trans "Appearance" %}</a>
{% for title, settings in groups %}
<a class="nav-link" href="#{{ title|slugify }}">{% trans title %}</a>
{% endfor %}
</div>
</nav>
</div>
<div class="col-lg-9">
<section class="card mb-3 settings-group" id="appearance" aria-labelledby="appearance-heading">
<div class="card-header"><h2 class="h5 mb-0" id="appearance-heading">{% trans "Appearance" %}</h2></div>
<div class="card-body row g-3">
<form action="{% url 'set_language' %}" method="post" class="col-md-6">{% csrf_token %}
<label class="form-label" for="language">{% trans "Language" %}</label>
<select id="language" name="language" class="form-select" aria-describedby="language-help">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>{{ language.name_local }} ({{ language.code }})</option>
{% endfor %}
</select>
<div id="language-help" class="form-text">{% trans "Yours only, in this browser" %}</div>
<button type="submit" class="btn btn-sm btn-outline-primary mt-2">{% trans "Change language" %}</button>
</form>
<form method="post" class="col-md-6">{% csrf_token %}
<label class="form-label" for="theme">{% trans bootstrap_theme.name %}</label>
<select id="theme" class="form-select" name="{{ bootstrap_theme.key }}" aria-describedby="theme-help">
{% for theme in themes_list %}
<option value="{{ theme }}"{% if bootstrap_theme.value == theme %} selected{% endif %}>{{ theme }}</option>
{% endfor %}
</select>
<div id="theme-help" class="form-text">{% trans "For every user" %}</div>
<button type="submit" class="btn btn-sm btn-outline-primary mt-2">{% trans "Change theme" %}</button>
</form>
</div>
</section>
{% for title, settings in groups %}
{% trans title as group_title %}
<section class="card mb-3 settings-group" id="{{ title|slugify }}" aria-labelledby="group-{{ forloop.counter }}">
<div class="card-header"><h2 class="h5 mb-0" id="group-{{ forloop.counter }}">{{ group_title }}</h2></div>
<form method="post" class="card-body">{% csrf_token %}
<div class="row g-3">
{% for setting in settings %}
<div class="col-md-6">
{% if setting.choices == "True,False" %}
{# an unchecked box posts nothing: the hidden False goes first, a checked box's True wins #}
<input type="hidden" name="{{ setting.key }}" value="False">
<div class="form-check form-switch">
<input id="setting-{{ setting.key }}" class="form-check-input" type="checkbox" role="switch" name="{{ setting.key }}" value="True"
{% if setting.value == "True" %}checked {% endif %}aria-describedby="help-{{ setting.key }}">
<label class="form-check-label" for="setting-{{ setting.key }}">{% trans setting.name %}</label>
</div>
{% else %}
<label class="form-label" for="setting-{{ setting.key }}">{% trans setting.name %}</label>
{% if setting.choices %}
<select id="setting-{{ setting.key }}" class="form-select" name="{{ setting.key }}" aria-describedby="help-{{ setting.key }}">
{% for choice in setting.choices_as_list %}
<option value="{{ choice }}"{% if setting.value == choice %} selected{% endif %}>{% trans choice %}</option>
{% endfor %}
</select>
{% elif setting.bounds %}
<input id="setting-{{ setting.key }}" class="form-control" type="number" name="{{ setting.key }}" value="{{ setting.value }}"
min="{{ setting.bounds.0 }}" max="{{ setting.bounds.1 }}" step="1" required aria-describedby="help-{{ setting.key }}">
{% else %}
<input id="setting-{{ setting.key }}" class="form-control" type="text" name="{{ setting.key }}" value="{{ setting.value }}"
maxlength="25" aria-describedby="help-{{ setting.key }}">
{% endif %}
{% endif %}
<input type="hidden" name="was-{{ setting.key }}" value="{{ setting.value }}">
<div id="help-{{ setting.key }}" class="form-text">{% trans setting.description %}</div>
</div>
{% endfor %}
</div>
<div class="border-top mt-3 pt-3 text-end">
<button type="submit" class="btn btn-primary">{% blocktrans %}Save {{ group_title }}{% endblocktrans %}</button>
</div>
</form>
</section>
{% endfor %}
</div>
</div>
{% endblock %}