mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 13:17:00 +04:00
94 lines
4.5 KiB
Plaintext
94 lines
4.5 KiB
Plaintext
---
|
|
import FormHint from '@ui/FormHint.astro'
|
|
import Button from '@ui/Button.astro'
|
|
import InputGroup from '@ui/InputGroup.astro'
|
|
import FormGroup from '@ui/FormGroup.astro'
|
|
---
|
|
|
|
<div class="modal-header">
|
|
<h4 class="modal-title" id="modal-change-password-title">Change password</h4>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<form>
|
|
<FormGroup label="Current password" for="password-current" class="mb-4">
|
|
<InputGroup type="password" id="password-current" placeholder="Enter your current password" autocomplete="current-password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
|
|
</FormGroup>
|
|
|
|
<FormGroup label="New password" for="password-new" class="mb-4">
|
|
<InputGroup type="password" id="password-new" placeholder="Enter new password" autocomplete="new-password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
|
|
<FormHint as="small"> Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji. </FormHint>
|
|
<div class="mt-2">
|
|
<div class="progress" style="height: 4px;">
|
|
<div class="progress-bar" id="password-strength" role="progressbar" style="width: 0%" aria-label="Password strength" aria-valuemin="0" aria-valuemax="5" aria-valuenow="0"></div>
|
|
</div>
|
|
<div class="text-secondary text-xs mt-1" id="password-strength-text" aria-live="polite"></div>
|
|
</div>
|
|
</FormGroup>
|
|
|
|
<FormGroup label="Confirm new password" for="password-confirm" class="mb-4">
|
|
<InputGroup type="password" id="password-confirm" placeholder="Confirm your new password" autocomplete="new-password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
|
|
<div class="invalid-feedback d-none" id="password-match-error" role="alert">Passwords do not match.</div>
|
|
</FormGroup>
|
|
|
|
<Button type="submit" text="Update password" color="primary" block class="mt-4" />
|
|
</form>
|
|
</div>
|
|
<!-- BEGIN CHANGE PASSWORD -->
|
|
<script>
|
|
// Password show/hide toggles are wired generically by InputGroup.astro (data-password-toggle).
|
|
const newPasswordInput = document.getElementById('password-new') as HTMLInputElement | null
|
|
const strengthBar = document.getElementById('password-strength')
|
|
const strengthText = document.getElementById('password-strength-text')
|
|
|
|
if (newPasswordInput && strengthBar && strengthText) {
|
|
newPasswordInput.addEventListener('input', function (this: HTMLInputElement) {
|
|
const password = this.value
|
|
let strength = 0
|
|
|
|
if (password.length >= 8) strength++
|
|
if (password.length >= 12) strength++
|
|
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) strength++
|
|
if (/\d/.test(password)) strength++
|
|
if (/[^a-zA-Z0-9]/.test(password)) strength++
|
|
|
|
const percentage = (strength / 5) * 100
|
|
strengthBar.style.width = `${percentage}%`
|
|
strengthBar.setAttribute('aria-valuenow', String(strength))
|
|
|
|
const strengthLevels = ['bg-danger', 'bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success']
|
|
const strengthLabels = ['Weak', 'Weak', 'Weak', 'Fair', 'Good', 'Strong']
|
|
strengthBar.className = `progress-bar ${strengthLevels[strength]}`
|
|
strengthBar.setAttribute('aria-valuetext', password ? (strengthLabels[strength] ?? '') : 'Empty')
|
|
strengthText.textContent = password ? (strengthLabels[strength] ?? '') : ''
|
|
})
|
|
}
|
|
|
|
const confirmPasswordInput = document.getElementById('password-confirm') as HTMLInputElement | null
|
|
const matchError = document.getElementById('password-match-error')
|
|
|
|
if (newPasswordInput && confirmPasswordInput && matchError) {
|
|
const validateMatch = () => {
|
|
const newPassword = newPasswordInput.value
|
|
const confirmPassword = confirmPasswordInput.value
|
|
|
|
if (confirmPassword && newPassword !== confirmPassword) {
|
|
confirmPasswordInput.classList.add('is-invalid')
|
|
confirmPasswordInput.setAttribute('aria-invalid', 'true')
|
|
confirmPasswordInput.setAttribute('aria-describedby', 'password-match-error')
|
|
matchError.classList.remove('d-none')
|
|
} else {
|
|
confirmPasswordInput.classList.remove('is-invalid')
|
|
confirmPasswordInput.removeAttribute('aria-invalid')
|
|
confirmPasswordInput.removeAttribute('aria-describedby')
|
|
matchError.classList.add('d-none')
|
|
}
|
|
}
|
|
|
|
newPasswordInput.addEventListener('input', validateMatch)
|
|
confirmPasswordInput.addEventListener('input', validateMatch)
|
|
}
|
|
</script>
|
|
<!-- END CHANGE PASSWORD -->
|