fix(post-form): load FilePond CSS in head + real success confirmation

Three field-reported bugs, all root-caused on the isolated test server:

1+2. FilePond's stylesheet never loaded — the filepond field registers it via
   assets.addCss() during body render, too late for the theme's head-only
   {{ assets.css() }}. Photo tiles rendered as giant unstyled boxes that
   stacked and overlapped the rest of the form (Get Location/Weather, Submit),
   making it unusable and looking like upload errors. Load filepond.min.css +
   image-preview CSS in the head_assets block; hide the PQINA credit.

3. The success notice rendered at the top of a long, reset form (off-screen
   after submitting from the bottom) and .notices was unstyled on the dark
   theme. Style .notices; on load, scroll the confirmation into view and inject
   a 'View your journal' link (to site.active_trip) + 'Post another' CTA.

Verified in a browser: 3 photos render compact without overlap; post-submit
shows the confirmation + working view link.
This commit is contained in:
2026-07-04 19:23:02 +02:00
parent c70e96879b
commit d3a520426a
5 changed files with 110 additions and 18 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+56 -13
View File
@@ -132,25 +132,68 @@
.btn-action[disabled] { opacity: 0.5; cursor: not-allowed; }
@keyframes post-spin { to { transform: rotate(360deg); } }
/* Grav form save/validation messages (success + error from the server) */
.post-form-wrap .form-messages { margin-bottom: var(--space-5); }
.post-form-wrap .form-message {
padding: 0.875rem 1rem;
/* Grav renders form status as <div class="notices success|error green|red">.
The theme doesn't style .notices, so on the dark background it was nearly
invisible — style it prominently here. */
.post-form-wrap .notices {
padding: 1rem 1.1rem;
border-radius: var(--radius-md);
font-size: var(--text-sm);
margin-bottom: var(--space-2);
}
.post-form-wrap .form-message.notice,
.post-form-wrap .form-message.error {
background: var(--color-accent-light);
font-size: var(--text-base);
margin: 0 0 var(--space-5);
background: var(--color-canvas);
color: var(--color-ink);
border: 1px solid var(--color-error);
border-left: 4px solid var(--color-accent);
}
.post-form-wrap .form-message.success {
.post-form-wrap .notices p { margin: 0; }
.post-form-wrap .notices.error,
.post-form-wrap .notices.red { border-left-color: var(--color-error); }
.post-form-wrap .notices.success,
.post-form-wrap .notices.green { border-left-color: var(--color-accent); }
/* Post-success confirmation CTA (injected by post-form.js). */
.post-success {
margin: 0 0 var(--space-5);
padding: 1.1rem;
border-radius: var(--radius-md);
background: var(--color-accent-light);
color: var(--color-ink);
border: 1px solid var(--color-accent);
}
.post-success__title {
font-family: var(--font-ui);
font-size: var(--text-md);
font-weight: 600;
color: var(--color-ink);
margin: 0 0 var(--space-3);
}
.post-success__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.post-success__view {
flex: 1;
min-width: 140px;
text-align: center;
padding: 0.8rem 1rem;
min-height: 44px;
border-radius: var(--radius-md);
background: var(--color-accent);
color: var(--color-accent-on);
font-weight: 600;
text-decoration: none;
}
.post-success__again {
flex: 1;
min-width: 140px;
text-align: center;
padding: 0.8rem 1rem;
min-height: 44px;
border-radius: var(--radius-md);
background: transparent;
color: var(--color-ink);
border: 1px solid var(--color-border);
font-weight: 600;
text-decoration: none;
}
/* Hide FilePond's "Powered by PQINA" credit. */
.filepond--credits { display: none !important; }
/* ── EasyMDE — Field Notes dark theme (U5) ─────────────────── */
.EasyMDEContainer .CodeMirror {
+43
View File
@@ -457,11 +457,54 @@ function initDraft() {
}
}
/* ── Post-success confirmation (issue: message was off-screen) ─────
* After a successful submit the page re-renders with Grav's success notice at
* the top of a long, reset form — easy to miss on mobile. Scroll it into view
* and add a "View your journal" / "Post another" CTA the owner can act on.
*/
function initSuccessState() {
var wrap = document.querySelector('.post-form-wrap');
var notice = document.querySelector('.post-form-wrap .notices.success, .post-form-wrap .notices.green');
if (!wrap || !notice) return;
var panel = document.createElement('div');
panel.className = 'post-success';
var title = document.createElement('p');
title.className = 'post-success__title';
title.textContent = '✓ Saved to your journal.';
panel.appendChild(title);
var actions = document.createElement('div');
actions.className = 'post-success__actions';
var tripUrl = wrap.getAttribute('data-trip-url');
if (tripUrl) {
var view = document.createElement('a');
view.className = 'post-success__view';
view.href = tripUrl;
view.textContent = 'View your journal →';
actions.appendChild(view);
}
var again = document.createElement('a');
again.className = 'post-success__again';
again.href = window.location.pathname; // reload /post fresh
again.textContent = 'Post another';
actions.appendChild(again);
panel.appendChild(actions);
notice.parentNode.insertBefore(panel, notice.nextSibling);
notice.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
/* ── Boot ────────────────────────────────────────────────── */
function boot() {
// Exposed for U6 draft restore and the Playwright specs; null when this
// bundle loads on a page without the content field.
window.postFormEditor = initEditor();
initSuccessState();
// Restore before disclosure/geo so their on-load checks (auto-open,
// weather-button enable) see the restored values.
initDraft();
@@ -1,12 +1,18 @@
{% extends 'default.html.twig' %}
{% block head_assets %}
{# FilePond's own CSS must load from the <head>. The filepond field registers
it via assets.addCss() during body rendering, which is too late for the
theme's head-only {{ assets.css() }} — so the widget renders unstyled
(giant overlapping tiles) unless we add it here. #}
{% do assets.addCss('plugin://form/assets/filepond/filepond.min.css') %}
{% do assets.addCss('plugin://form/assets/filepond/filepond-plugin-image-preview.min.css') %}
{% do assets.addCss('theme://css-compiled/post-form.css') %}
<script type="module" src="{{ url('theme://js/post/post-form.js') }}"></script>
{% endblock %}
{% block content %}
<div class="post-form-wrap">
<div class="post-form-wrap" data-trip-url="{{ config.site.active_trip }}">
<h1>New Entry</h1>
{% include 'forms/form.html.twig' ignore missing %}