{% extends "layout.html.tera" %}
{% block title %}Settings — {{ app_display }}{% endblock title %}
{% block content %}
<nav class="breadcrumb-nav" aria-label="Breadcrumb">
<ol class="breadcrumb-list" aria-label="Breadcrumb trail">
<li class="breadcrumb-list-item"><a href="/">Home</a></li>
<li class="breadcrumb-list-item" aria-current="page">Settings</li>
</ol>
</nav>
<section aria-label="User settings"
x-data='{
settings: JSON.parse(localStorage.getItem("lily-settings") || "{}"),
save() {
localStorage.setItem("lily-settings", JSON.stringify(this.settings));
if (window.lily && window.lily.toast) {
window.lily.toast("Settings saved", "success");
}
},
reset() {
this.settings = {};
localStorage.removeItem("lily-settings");
if (window.lily && window.lily.toast) {
window.lily.toast("Settings reset", "info");
}
},
toggle(key) {
this.settings[key] = !this.settings[key];
this.save();
}
}'>
<h2>Settings</h2>
<p>
<span class="hint" aria-label="Settings description">
Per-browser preferences. Stored in <code>localStorage["lily-settings"]</code>;
no server round-trip required.
</span>
</p>
<div class="action-bar" role="toolbar" aria-label="Settings shortcuts">
<a class="button"
href="/tokens"
aria-label="Manage personal API tokens">API tokens</a>
</div>
<form class="form" aria-label="Settings form" @submit.prevent="save()">
<fieldset class="fieldset" aria-label="Display preferences">
<legend>Display</legend>
<div class="field" aria-label="Mask sensitive fields preference">
<label class="label" for="mask-sensitive-default">Mask sensitive fields by default</label>
<span class="hint" id="mask-sensitive-default-hint">
Apply privacy masking to identifiers, phones, SSN, NHS number in lists and search.
</span>
<button class="switch-button"
role="switch"
type="button"
id="mask-sensitive-default"
aria-label="Mask sensitive fields by default"
aria-describedby="mask-sensitive-default-hint"
x-bind:aria-checked="settings.mask_sensitive_default ? 'true' : 'false'"
@click="toggle('mask_sensitive_default')">
<span x-text="settings.mask_sensitive_default ? 'On' : 'Off'"></span>
</button>
</div>
<div class="field" aria-label="Show inactive preference">
<label class="label" for="show-inactive">Show inactive records in lists</label>
<span class="hint" id="show-inactive-hint">
When off, soft-deleted records are hidden from the index and search.
</span>
<button class="switch-button"
role="switch"
type="button"
id="show-inactive"
aria-label="Show inactive records"
aria-describedby="show-inactive-hint"
x-bind:aria-checked="settings.show_inactive ? 'true' : 'false'"
@click="toggle('show_inactive')">
<span x-text="settings.show_inactive ? 'On' : 'Off'"></span>
</button>
</div>
<div class="field" aria-label="Toast notifications preference">
<label class="label" for="toasts-on">Toast notifications</label>
<span class="hint" id="toasts-on-hint">
Show transient confirmation messages after actions like merge / delete.
</span>
<button class="switch-button"
role="switch"
type="button"
id="toasts-on"
aria-label="Toast notifications"
aria-describedby="toasts-on-hint"
x-bind:aria-checked="settings.toasts_on === false ? 'false' : 'true'"
@click="toggle('toasts_on')">
<span x-text="settings.toasts_on === false ? 'Off' : 'On'"></span>
</button>
</div>
<div class="field" aria-label="Page size preference">
<label class="label" for="page-size">Page size</label>
<span class="hint" id="page-size-hint">Rows per page on the index and search.</span>
<select class="select"
id="page-size"
aria-label="Page size"
aria-describedby="page-size-hint"
x-model.number="settings.page_size"
@change="save()">
<option class="option" value="10">10</option>
<option class="option" value="25" selected>25</option>
<option class="option" value="50">50</option>
<option class="option" value="100">100</option>
</select>
</div>
</fieldset>
<fieldset class="fieldset" aria-label="Accent color preferences"
x-data='{
presets: [
{ value: "#005eb8", name: "NHS blue" },
{ value: "#330072", name: "Purple" },
{ value: "#7c2855", name: "Dark pink" },
{ value: "#8a1538", name: "Dark red" },
{ value: "#ed8b00", name: "Orange" },
{ value: "#006747", name: "Dark green" },
{ value: "#00a499", name: "Aqua green" },
{ value: "#231f20", name: "Charcoal" }
],
accent: localStorage.getItem("lily-accent") || "",
apply(v) {
this.accent = v;
if (v) {
document.documentElement.style.setProperty("--nhs-blue", v);
localStorage.setItem("lily-accent", v);
} else {
document.documentElement.style.removeProperty("--nhs-blue");
localStorage.removeItem("lily-accent");
}
if (window.lily && window.lily.toast) {
window.lily.toast("Accent updated", "info");
}
}
}'>
<legend>Accent color</legend>
<div class="field" aria-label="Accent presets field">
<label class="label" for="accent-picker">Pick a preset</label>
<span class="hint" id="accent-picker-hint">Overrides the primary blue (<code>--nhs-blue</code>) on every page.</span>
<div class="color-picker"
id="accent-picker"
role="radiogroup"
aria-label="Accent color presets"
aria-describedby="accent-picker-hint">
<template x-for="p in presets" :key="p.value">
<button class="color-picker-button"
type="button"
role="radio"
x-bind:aria-label="'Set accent to ' + p.name"
x-bind:aria-checked="accent === p.value ? 'true' : 'false'"
x-bind:style="'background-color: ' + p.value"
@click="apply(p.value)"></button>
</template>
</div>
</div>
<div class="field" aria-label="Custom accent field">
<label class="label" for="accent-input">Custom hex</label>
<span class="hint" id="accent-input-hint">Use the native color picker for any color outside the presets.</span>
<input class="color-input"
type="color"
id="accent-input"
aria-label="Custom accent color"
aria-describedby="accent-input-hint"
x-bind:value="accent || '#005eb8'"
@change="apply($event.target.value)">
</div>
<div class="action-bar" role="toolbar" aria-label="Accent actions">
<button class="button"
type="button"
aria-label="Reset accent to NHS blue"
@click="apply('')">Reset to default</button>
<span class="action-bar-count">
Current: <code x-text="accent || '(default)'"></code>
</span>
</div>
</fieldset>
<fieldset class="fieldset" aria-label="Diagnostics preferences">
<legend>Diagnostics</legend>
<div class="field" aria-label="Show technical detail preference">
<label class="label" for="show-detail">Show technical detail on error pages</label>
<span class="hint" id="show-detail-hint">
Expand the technical-detail <code><details></code> block on 500 pages by default.
</span>
<button class="switch-button"
role="switch"
type="button"
id="show-detail"
aria-label="Show technical detail"
aria-describedby="show-detail-hint"
x-bind:aria-checked="settings.show_detail ? 'true' : 'false'"
@click="toggle('show_detail')">
<span x-text="settings.show_detail ? 'On' : 'Off'"></span>
</button>
</div>
</fieldset>
<div class="action-bar" role="toolbar" aria-label="Settings actions">
<button class="button" type="submit" aria-label="Save settings">Save</button>
<button class="button"
type="button"
aria-label="Reset settings to defaults"
@click="reset()">Reset</button>
</div>
</form>
</section>
{% endblock content %}