feat(post-form): require 1–6 photos per entry

Raise the FilePond limit from 4 to 6 and enforce a minimum of one photo.
The photo field is first in the form, so initValidation checks it first: an
empty picker blocks submit, reveals the (possibly collapsed) photo section,
and shows "Add at least one photo." under its header. Labels updated to
"Photos (1–6)".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 20:59:01 +02:00
co-authored by Claude Opus 4.8
parent 1cde137daa
commit 8b037511fd
3 changed files with 67 additions and 36 deletions
File diff suppressed because one or more lines are too long
+32 -3
View File
@@ -120,7 +120,7 @@ function buildPhotoCollapse() {
details.open = true;
var summary = document.createElement('summary');
summary.className = 'photos-collapse__summary';
summary.textContent = 'Photos (max 4)';
summary.textContent = 'Photos (16)';
details.appendChild(summary);
// Relocate the existing control (+ label/status) into the details body.
@@ -188,7 +188,7 @@ function initPhotoConversion() {
collapse.summary.textContent = '✓ ' + total + ' photo' + (total > 1 ? 's' : '') + ' ready — tap to review';
collapse.details.open = false; // auto-collapse when settled
} else {
collapse.summary.textContent = 'Photos (max 4)';
collapse.summary.textContent = 'Photos (16)';
collapse.details.open = true;
}
}
@@ -469,11 +469,40 @@ function initValidation() {
el.parentNode.insertBefore(err, el.nextSibling);
}
// At least one photo is required. The picker is first in the form, so if it
// is empty this is the first invalid field — reveal the (possibly collapsed)
// section, show the message under its header, and return an element to
// scroll to. Uses the same .field-error class so clearErrors() cleans it up.
function showPhotoError(msg) {
var collapse = form.querySelector('.photos-collapse');
var host, anchor;
if (collapse) {
collapse.open = true; // reveal the drop zone + message
anchor = collapse.querySelector('.photos-collapse__summary');
host = collapse;
} else {
host = document.querySelector('.filepond-root, .form-input-file');
anchor = host;
}
if (!anchor) return host || null;
var err = document.createElement('span');
err.className = 'field-error';
err.textContent = msg;
anchor.insertAdjacentElement('afterend', err);
return host || anchor;
}
// Bubble phase: runs after initEditor's capture-phase codemirror.save(), so
// the content textarea already holds the live value.
form.addEventListener('submit', function (e) {
clearErrors();
var firstInvalid = null;
// ≥1 photo (photos are the first field). Count any present FilePond item.
if (document.querySelectorAll('.filepond--item').length < 1) {
firstInvalid = showPhotoError('Add at least one photo.');
}
Object.keys(REQUIRED).forEach(function (name) {
var el = field(name);
if (el && !String(el.value).trim()) {
@@ -483,7 +512,7 @@ function initValidation() {
});
if (firstInvalid) {
e.preventDefault();
firstInvalid.focus();
if (typeof firstInvalid.focus === 'function') firstInvalid.focus();
firstInvalid.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
});