smtp: typed probe errors with per-field UI highlighting on save

This commit is contained in:
Pontoporeia
2026-04-30 12:16:52 +02:00
parent b750aca2f5
commit bdb68479d5
7 changed files with 341 additions and 198 deletions

View File

@@ -183,7 +183,27 @@
<?php endif; ?>
</div>
<form method="post" action="actions/settings.php" class="param-form">
<?php
// Inline helper: emit aria-invalid + error <small> when this field is the culprit
$smtpFieldErr = function(string $id) use ($smtpErrorField): string {
return $smtpErrorField === $id ? ' aria-invalid="true"' : '';
};
$smtpFieldMsg = function(string $id, string $msg) use ($smtpErrorField): string {
return $smtpErrorField === $id
? '<small class="param-field-error" id="' . $id . '-error">' . htmlspecialchars($msg) . '</small>'
: '';
};
// Human-readable hints per field (brief — the full message is in the toast)
$smtpHints = [
'smtp_host' => 'Vérifiez ladresse du serveur SMTP.',
'smtp_port' => 'Vérifiez le numéro de port.',
'smtp_encryption' => 'Vérifiez le mode de chiffrement.',
'smtp_username' => 'Vérifiez le nom dutilisateur.',
'smtp_password' => 'Mot de passe incorrect.',
];
?>
<form method="post" action="actions/settings.php" class="param-form"
<?= $smtpErrorField ? 'data-smtp-error-field="' . htmlspecialchars($smtpErrorField) . '"' : '' ?>>
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="section" value="smtp">
@@ -192,29 +212,41 @@
<label for="smtp_host">Hôte SMTP</label>
<input type="text" id="smtp_host" name="smtp_host"
value="<?= htmlspecialchars($smtpSettings['host']) ?>"
placeholder="smtp.example.com">
placeholder="smtp.example.com"
<?= $smtpFieldErr('smtp_host') ?>
<?= $smtpErrorField === 'smtp_host' ? 'aria-describedby="smtp_host-error"' : '' ?>>
<?= $smtpFieldMsg('smtp_host', $smtpHints['smtp_host']) ?>
</div>
<div>
<label for="smtp_port">Port</label>
<input type="number" id="smtp_port" name="smtp_port"
value="<?= (int)$smtpSettings['port'] ?>"
min="1" max="65535">
min="1" max="65535"
<?= $smtpFieldErr('smtp_port') ?>
<?= $smtpErrorField === 'smtp_port' ? 'aria-describedby="smtp_port-error"' : '' ?>>
<?= $smtpFieldMsg('smtp_port', $smtpHints['smtp_port']) ?>
</div>
<div>
<label for="smtp_encryption">Chiffrement</label>
<select id="smtp_encryption" name="smtp_encryption">
<select id="smtp_encryption" name="smtp_encryption"
<?= $smtpFieldErr('smtp_encryption') ?>
<?= $smtpErrorField === 'smtp_encryption' ? 'aria-describedby="smtp_encryption-error"' : '' ?>>
<option value="tls" <?= $smtpSettings['encryption'] === 'tls' ? 'selected' : '' ?>>TLS (STARTTLS)</option>
<option value="ssl" <?= $smtpSettings['encryption'] === 'ssl' ? 'selected' : '' ?>>SSL (SMTPS)</option>
<option value="none" <?= $smtpSettings['encryption'] === 'none' ? 'selected' : '' ?>>Aucun</option>
</select>
<?= $smtpFieldMsg('smtp_encryption', $smtpHints['smtp_encryption']) ?>
</div>
<div>
<label for="smtp_username">Nom d'utilisateur</label>
<input type="text" id="smtp_username" name="smtp_username"
value="<?= htmlspecialchars($smtpSettings['username']) ?>">
value="<?= htmlspecialchars($smtpSettings['username']) ?>"
<?= $smtpFieldErr('smtp_username') ?>
<?= $smtpErrorField === 'smtp_username' ? 'aria-describedby="smtp_username-error"' : '' ?>>
<?= $smtpFieldMsg('smtp_username', $smtpHints['smtp_username']) ?>
</div>
<div>
@@ -222,7 +254,10 @@
<input type="password" id="smtp_password" name="smtp_password"
value="<?= htmlspecialchars($smtpSettings['password']) ?>"
autocomplete="new-password"
placeholder="Laissez vide pour ne pas modifier">
placeholder="Laissez vide pour ne pas modifier"
<?= $smtpFieldErr('smtp_password') ?>
<?= $smtpErrorField === 'smtp_password' ? 'aria-describedby="smtp_password-error"' : '' ?>>
<?= $smtpFieldMsg('smtp_password', $smtpHints['smtp_password']) ?>
</div>
</div>
@@ -507,6 +542,17 @@ function fallbackCopy(text, btn) {
} catch(e) {}
document.body.removeChild(ta);
}
// Focus the SMTP field that caused the probe error
(function () {
var form = document.querySelector('form[data-smtp-error-field]');
if (!form) return;
var fieldId = form.getAttribute('data-smtp-error-field');
var el = fieldId ? document.getElementById(fieldId) : null;
if (!el) return;
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
el.focus();
}());
// Update active tab class after each HTMX swap on #sys-tab-panel
document.body.addEventListener('htmx:afterSwap', function(evt) {
if (evt.detail.target && evt.detail.target.id === 'sys-tab-panel') {