Files
xamxam/app/public/assets/js/app/access-request.js
Pontoporeia 99125cc8e3 Add autosave draft system for partage form with HTMX-based session persistence
- New fragment endpoint POST/GET /partage/fragments/draft.php:
  saves all form fields to PHP session, excludes file/csrf/slug fields
  GET returns JSON for JS hydration on page load
  rotates both global CSRF and share CSRF tokens in sync

- form.php accepts optional $formExtraAttrs and $showAutosaveStatus:
  allows injecting HTMX attributes and 'Brouillon enregistré' indicator

- renderShareLinkForm adds hx-post with change/input debounce trigger,
  loads autosave-handler.js, hydrate fields from draft on page load

- Draft cleared on successful form submission in handleShareLinkSubmission

- autosave-handler.js now also updates share_link_token hidden input
  when rotating CSRF token (partage form uses both csrf_token and share_link_token)

- Added .autosave-status CSS to form.css (was admin.css-only)

- Updated fragment routing to accept GET requests (needed for draft hydration)
2026-06-11 11:04:49 +02:00

102 lines
3.5 KiB
JavaScript

/**
* access-request.js — handles the "Demander l'accès" form on public thesis pages.
*
* Shows/hides the justification textarea based on email domain (@erg.school / @erg.be).
* Submits via fetch() to /request-access and displays success/error messages.
* Handles the special "recipient_rejected" status to let the user fix their email.
*
* Expects a form with:
* #access-request-form — the form (needs data-thesis-id)
* #access-email — email input
* #justification-container — wrapper div for justification
* #access-justification — justification textarea
* #access-request-message — message display div
*/
(() => {
var form = document.getElementById("access-request-form");
if (!form) return;
var emailInput = document.getElementById("access-email");
var justificationContainer = document.getElementById(
"justification-container",
);
var justificationInput = document.getElementById("access-justification");
var messageDiv = document.getElementById("access-request-message");
if (!emailInput || !messageDiv) return;
// Show/hide justification based on email domain
emailInput.addEventListener("input", function () {
var email = this.value.trim().toLowerCase();
var isErg = email.endsWith("@erg.school") || email.endsWith("@erg.be");
if (justificationContainer)
justificationContainer.style.display = isErg ? "none" : "block";
if (justificationInput) justificationInput.required = !isErg;
});
function showRetryPrompt(rejectedEmail, serverMessage) {
messageDiv.style.display = "block";
messageDiv.className = "tfe-access-message tfe-access-error";
messageDiv.innerHTML =
"<strong>Adresse e-mail introuvable sur le serveur de l'ERG.</strong><br>" +
"<small>" +
serverMessage.replace(/</g, "&lt;") +
"</small><br><br>" +
"Corrigez votre adresse e-mail et réessayez.";
emailInput.value = rejectedEmail;
emailInput.classList.add("input-error");
emailInput.focus();
emailInput.select();
emailInput.addEventListener("input", function clearError() {
emailInput.classList.remove("input-error");
emailInput.removeEventListener("input", clearError);
});
}
form.addEventListener("submit", (e) => {
e.preventDefault();
var submitBtn = form.querySelector('button[type="submit"]');
submitBtn.disabled = true;
submitBtn.textContent = "Envoi en cours...";
messageDiv.style.display = "none";
var submittedEmail = emailInput.value.trim();
var formData = new FormData(form);
formData.append("thesis_id", form.getAttribute("data-thesis-id"));
fetch("/request-access", {
method: "POST",
body: formData,
})
.then((response) => response.json())
.then((data) => {
submitBtn.disabled = false;
submitBtn.textContent = "Demander l'accès";
if (data.status === "recipient_rejected") {
showRetryPrompt(submittedEmail, data.message);
return;
}
messageDiv.style.display = "block";
if (data.success) {
messageDiv.className = "tfe-access-message tfe-access-success";
messageDiv.textContent = data.message;
form.reset();
} else {
messageDiv.className = "tfe-access-message tfe-access-error";
messageDiv.textContent =
data.message || "Une erreur est survenue. Veuillez réessayer.";
}
})
.catch(() => {
submitBtn.disabled = false;
submitBtn.textContent = "Demander l'accès";
messageDiv.style.display = "block";
messageDiv.className = "tfe-access-message tfe-access-error";
messageDiv.textContent = "Erreur de connexion. Veuillez réessayer.";
});
});
})();