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:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -132,25 +132,68 @@
|
|||||||
.btn-action[disabled] { opacity: 0.5; cursor: not-allowed; }
|
.btn-action[disabled] { opacity: 0.5; cursor: not-allowed; }
|
||||||
@keyframes post-spin { to { transform: rotate(360deg); } }
|
@keyframes post-spin { to { transform: rotate(360deg); } }
|
||||||
|
|
||||||
/* Grav form save/validation messages (success + error from the server) */
|
/* Grav renders form status as <div class="notices success|error green|red">.
|
||||||
.post-form-wrap .form-messages { margin-bottom: var(--space-5); }
|
The theme doesn't style .notices, so on the dark background it was nearly
|
||||||
.post-form-wrap .form-message {
|
invisible — style it prominently here. */
|
||||||
padding: 0.875rem 1rem;
|
.post-form-wrap .notices {
|
||||||
|
padding: 1rem 1.1rem;
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-base);
|
||||||
margin-bottom: var(--space-2);
|
margin: 0 0 var(--space-5);
|
||||||
}
|
background: var(--color-canvas);
|
||||||
.post-form-wrap .form-message.notice,
|
|
||||||
.post-form-wrap .form-message.error {
|
|
||||||
background: var(--color-accent-light);
|
|
||||||
color: var(--color-ink);
|
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);
|
background: var(--color-accent-light);
|
||||||
color: var(--color-ink);
|
|
||||||
border: 1px solid var(--color-accent);
|
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) ─────────────────── */
|
/* ── EasyMDE — Field Notes dark theme (U5) ─────────────────── */
|
||||||
.EasyMDEContainer .CodeMirror {
|
.EasyMDEContainer .CodeMirror {
|
||||||
|
|||||||
@@ -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 ────────────────────────────────────────────────── */
|
/* ── Boot ────────────────────────────────────────────────── */
|
||||||
function boot() {
|
function boot() {
|
||||||
// Exposed for U6 draft restore and the Playwright specs; null when this
|
// Exposed for U6 draft restore and the Playwright specs; null when this
|
||||||
// bundle loads on a page without the content field.
|
// bundle loads on a page without the content field.
|
||||||
window.postFormEditor = initEditor();
|
window.postFormEditor = initEditor();
|
||||||
|
initSuccessState();
|
||||||
// Restore before disclosure/geo so their on-load checks (auto-open,
|
// Restore before disclosure/geo so their on-load checks (auto-open,
|
||||||
// weather-button enable) see the restored values.
|
// weather-button enable) see the restored values.
|
||||||
initDraft();
|
initDraft();
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
{% extends 'default.html.twig' %}
|
{% extends 'default.html.twig' %}
|
||||||
|
|
||||||
{% block head_assets %}
|
{% 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') %}
|
{% do assets.addCss('theme://css-compiled/post-form.css') %}
|
||||||
<script type="module" src="{{ url('theme://js/post/post-form.js') }}"></script>
|
<script type="module" src="{{ url('theme://js/post/post-form.js') }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="post-form-wrap">
|
<div class="post-form-wrap" data-trip-url="{{ config.site.active_trip }}">
|
||||||
<h1>New Entry</h1>
|
<h1>New Entry</h1>
|
||||||
{% include 'forms/form.html.twig' ignore missing %}
|
{% include 'forms/form.html.twig' ignore missing %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user