Skip to content

Commit 1fa98d3

Browse files
committed
Refactor: extract password toggle to macro and put SVGs in files
1 parent 136c630 commit 1fa98d3

4 files changed

Lines changed: 51 additions & 36 deletions

File tree

src/adminui/templates/auth/login.html

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{% extends "raw_base.html" %}
22

3+
{# import the macro file to use the password function #}
4+
{% from "macros.html" import password_input %}
5+
36
{% block theme %}light{% endblock %}
47
{% block title %}Sign into Kiwix Admin{% endblock %}
58

@@ -71,51 +74,34 @@
7174
<label class="form-label" for="username">Username</label>
7275
<input type="text" class="form-control{% if is_incorrect %} is-invalid{% endif %}" name="username" placeholder="Usually “admin”" />
7376
</div>
74-
<div class="mb-3">
75-
<label class="form-label" for="password">Password</label>
76-
<div class="input-group">
77-
<input type="password" id="password-input" class="form-control{% if is_incorrect %} is-invalid{% endif %}" name="password" aria-describedby="credentialsFeedback">
78-
79-
<button class="btn btn-outline-secondary" type="button" id="toggle-password">
80-
<svg id="eye-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
81-
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
82-
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5z"/>
83-
</svg>
84-
<svg id="eye-slash-icon" style="display: none;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
85-
<path d="M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z"/>
86-
<path d="M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z"/>
87-
<path d="M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12-.708.708z"/>
88-
</svg>
89-
</button>
90-
{% if is_incorrect and message_content %}<div id="credentialsFeedback" class="invalid-feedback">{{ message_content }}</div>{% endif %}
91-
</div>
92-
</div>
77+
{{ password_input(name="password", error=message_content if is_incorrect else None) }}
9378
<div class="d-flex flex-row-reverse">
9479
<input type="submit" class="btn btn-primary" value="Sign-in" />
9580
</div>
9681
</form>
9782
</div>
9883
<div class="mt-1 mb-1 p-3"><a class="returnlink" href="http://{{ ctx.fqdn }}"><i class="fa-solid fa-arrow-left"></i> Return to the Hotspot</a></div>
84+
{% endblock %}
9985

86+
{% block javascript %}
10087
<script>
101-
const toggleButton = document.querySelector('#toggle-password');
102-
const password = document.querySelector('#password-input');
103-
const eyeIcon = document.querySelector('#eye-icon');
104-
const eyeSlashIcon = document.querySelector('#eye-slash-icon');
88+
document.querySelectorAll('.password-toggle').forEach(button => {
89+
button.addEventListener('click', function () {
90+
// Find the input that lives in the same group as this button
91+
const input = this.parentElement.querySelector('.password-input');
92+
const iconShow = this.querySelector('.icon-show');
93+
const iconHide = this.querySelector('.icon-hide');
10594

106-
toggleButton.addEventListener('click', function (e) {
107-
// Toggle the password visibility
108-
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
109-
password.setAttribute('type', type);
110-
111-
// Toggle the SVG icons
112-
if (type === 'text') {
113-
eyeIcon.style.display = 'none';
114-
eyeSlashIcon.style.display = 'block';
115-
} else {
116-
eyeIcon.style.display = 'block';
117-
eyeSlashIcon.style.display = 'none';
118-
}
95+
if (input.getAttribute('type') === 'password') {
96+
input.setAttribute('type', 'text');
97+
iconShow.style.display = 'none';
98+
iconHide.style.display = 'block';
99+
} else {
100+
input.setAttribute('type', 'password');
101+
iconShow.style.display = 'block';
102+
iconHide.style.display = 'none';
103+
}
104+
});
119105
});
120106
</script>
121107
{% endblock %}
Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 4 additions & 0 deletions
Loading

src/adminui/templates/macros.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{% macro password_input(name, label="Password", placeholder="", error=None) %}
2+
<div class="mb-3">
3+
<label class="form-label" for="{{ name }}">{{ label }}</label>
4+
<div class="input-group">
5+
<input type="password"
6+
class="form-control password-input {% if error %}is-invalid{% endif %}"
7+
name="{{ name }}"
8+
id="{{ name }}"
9+
placeholder="{{ placeholder }}"
10+
{% if error %}aria-describedby="{{ name }}Feedback"{% endif %}>
11+
12+
<button class="btn btn-outline-secondary password-toggle" type="button">
13+
{% include "icons/eye.svg" %}
14+
{% include "icons/eye-slash.svg" %}
15+
</button>
16+
17+
{% if error %}<div id="{{ name }}Feedback" class="invalid-feedback">{{ error }}</div>{% endif %}
18+
</div>
19+
</div>
20+
{% endmacro %}

0 commit comments

Comments
 (0)