{% extends "base.twig" %}
{% block title %}{{ t('ui.forgot_password.title', {}, 'common') }} - {{ parent() }}{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6 col-lg-4">
<div class="card">
<div class="card-header">
<h4 class="mb-0">
<i class="fas fa-key"></i>
{{ t('ui.forgot_password.reset_password', {}, 'common') }}
</h4>
</div>
<div class="card-body">
<p class="text-muted mb-4">
{{ t('ui.forgot_password.instructions', {}, 'common') }}
</p>
<form id="forgotPasswordForm">
<div class="mb-3">
<label for="usernameOrEmail" class="form-label">{{ t('ui.forgot_password.username_or_email', {}, 'common') }}</label>
<input type="text" class="form-control" id="usernameOrEmail" name="usernameOrEmail" required>
<div class="form-text">
{{ t('ui.forgot_password.username_or_email_help', {}, 'common') }}
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary" id="submitBtn">
<i class="fas fa-paper-plane"></i>
{{ t('ui.forgot_password.send_reset_link', {}, 'common') }}
</button>
</div>
</form>
<div id="successMessage" class="alert alert-success mt-3" style="display: none;"></div>
<div id="errorMessage" class="alert alert-danger mt-3" style="display: none;"></div>
</div>
</div>
<div class="text-center mt-3">
<small class="text-muted">
{{ t('ui.forgot_password.remember_password', {}, 'common') }} <a href="/login" class="text-decoration-none">{{ t('ui.forgot_password.back_to_login', {}, 'common') }}</a>
</small>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
function uiT(key, fallback, params = {}) {
if (window.t) {
return window.t(key, params, fallback);
}
return fallback;
}
$('#forgotPasswordForm').on('submit', function(e) {
e.preventDefault();
const formData = {
usernameOrEmail: $('#usernameOrEmail').val()
};
// Hide previous messages
$('#successMessage').hide();
$('#errorMessage').hide();
// Disable submit button
const submitBtn = $('#submitBtn');
const originalText = submitBtn.html();
submitBtn.prop('disabled', true).html(`<i class="fas fa-spinner fa-spin"></i> ${uiT('ui.forgot_password.sending', 'Sending...')}`);
$.ajax({
url: '/api/auth/forgot-password',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(formData),
success: function(response) {
if (response.success) {
const successText = window.getApiMessage
? window.getApiMessage(response, uiT('ui.forgot_password.reset_link_sent_if_exists', 'If an account with that username, real name, or email exists, a password reset link has been sent.'))
: uiT('ui.forgot_password.reset_link_sent_if_exists', 'If an account with that username, real name, or email exists, a password reset link has been sent.');
$('#successMessage').html(
`<strong>${uiT('ui.common.success', 'Success')}</strong><br>` +
successText +
`<br><br>${uiT('ui.forgot_password.check_email_notice', 'Please check your email inbox (and spam folder) for the reset link.')}`
).show();
$('#forgotPasswordForm')[0].reset();
}
},
error: function(xhr) {
const error = window.getApiErrorMessage
? window.getApiErrorMessage(xhr.responseJSON, uiT('ui.forgot_password.request_failed', 'Failed to process request'))
: uiT('ui.forgot_password.request_failed', 'Failed to process request');
$('#errorMessage').html(`<strong>${uiT('ui.common.error', 'Error')}</strong><br>${error}`).show();
},
complete: function() {
// Re-enable submit button after a short delay
setTimeout(function() {
submitBtn.prop('disabled', false).html(originalText);
}, 2000);
}
});
});
</script>
{% endblock %}
|