fix(forms): close completed drawers and restore portal styling
This commit is contained in:
15 files changed
+598
-9
No files matched your search
@@ -3,9 +3,9 @@
|
||||
**Last updated:** October 30, 2026 (UTC)
|
||||
**Repository:** `AIAMarketing/azinstitute4autism.com`
|
||||
**Working branch:** `faithful-astro-migration`
|
||||
**Last accepted technical implementation:** Phase 9 isolated consultation integration at `ff80ee516f0185023af1f29937e29dfb30d31f47`; this handoff also describes the consolidated service-drawer and employee-portal checkpoint candidate
|
||||
**Last accepted technical implementation:** consolidated service drawers and employee-portal preview at `e97f0ea9b475715a1ea58110a27cdf50a2b3cb19`; the commit containing this handoff adds the focused completion/styling correction pass
|
||||
**Previous accepted checkpoint:** P9-03 documentation, signed `537f9864a0a3d0806180cbeca909bf1d03200c6f`
|
||||
**Implementation checkpoint:** the commit containing this handoff update; obtain its actual SHA from Git history after the user creates the signed commit.
|
||||
**Implementation checkpoint:** the commit containing this handoff update; obtain its actual SHA from Git history after the signed checkpoint is created.
|
||||
**Next milestone:** continue Phase 9 owner decisions and authorized integration batches; then Phase 10 — Final QA/Cutover Readiness.
|
||||
|
||||
The landing-page migration is technically completed for checkpoint purposes.
|
||||
@@ -401,3 +401,34 @@ staff/management authorization. See
|
||||
and [owner utility instructions](../integrations/employee-portal/README.md).
|
||||
The actual checkpoint SHA is the commit containing this section; obtain it from
|
||||
Git history. No push, deployment or cutover is authorized by this work.
|
||||
|
||||
## Focused completion, portal styling and Spanish diagnostic — 2026-10-30
|
||||
|
||||
Authorized consultation drawers now accept only the documented
|
||||
`submission-completed` / `formID` envelope from their activated iframe window
|
||||
at the exact configured Jotform origin while the drawer is open. Object and
|
||||
bounded JSON-string envelopes are supported; other actions/messages are ignored.
|
||||
Completion writes the existing global 30-day expiry immediately, reveals EN/ES
|
||||
acknowledgment, then starts slide-out after five seconds. Manual dismissal or
|
||||
navigation cancels the countdown. Duplicate completion cannot restart it.
|
||||
The next deliberate opening replaces the completed iframe; incomplete forms
|
||||
remain intact across ordinary close/reopen. Load remains fallback-only, never
|
||||
submission evidence. Real provider-message acceptance requires one owner-run
|
||||
synthetic submission; automated tests use intercepted local fixtures only.
|
||||
|
||||
Portal presentation now restores scoped blue headings, spacing, directories,
|
||||
orange report buttons and accessible contact accents without retaining arbitrary
|
||||
classes, styles or scripts. Two synthetic encrypted views are verified. Private
|
||||
source exposed no plaintext class/CSS semantics, and real view codes were not
|
||||
available; exact legacy button recognition and visual parity require owner review.
|
||||
No private content/resource or ciphertext was added to Git or public output.
|
||||
|
||||
The reported seven-option Spanish consultation dropdown is an unresolved
|
||||
Jotform configuration issue: generated EN/ES URLs have identical form ID and
|
||||
`formContext=consultation`, differing only in `language`. Astro neither supplies
|
||||
nor edits child dropdown options. Owner should compare the direct hosted Spanish
|
||||
form and review multilingual option translations/Update Options conditions.
|
||||
No account changes or real submissions were performed. Seven production and
|
||||
nine isolated-test placements remain unchanged; production consultation, portal
|
||||
cutover and site cutover remain unauthorized. See the
|
||||
[focused correction evidence](phase-9-drawer-portal-corrections-2026-10-30.md).
|
||||
@@ -4350,3 +4350,20 @@ owner input. A passive DOM renderer intentionally disallows executable markup,
|
||||
remote media and embedded forms; real-view fidelity therefore needs owner review.
|
||||
No internal resource was published. Full evidence and boundaries are in
|
||||
[the consolidated report](phase-9-service-portal-consolidated-2026-10-30.md).
|
||||
|
||||
### Focused correction addendum, 2026-10-30
|
||||
|
||||
Consultation drawers now acknowledge strictly verified provider completion for
|
||||
five seconds before the existing slide-out, establish the shared 30-day
|
||||
suppression immediately, and offer a fresh iframe on subsequent manual opening.
|
||||
This owner-authorized behavior is isolated-test-only for the nine consultation
|
||||
placements. Provider acceptance is pending; no real submission was generated.
|
||||
|
||||
Portal typography, spacing, tables and narrow safe button mappings restore AIA
|
||||
visual hierarchy in synthetic encrypted views. The contact-link orange is
|
||||
darkened to `#a94600` for text contrast on white; buttons preserve existing
|
||||
orange/blue design tokens. Actual unlocked source parity remains owner review
|
||||
because credentials were unavailable. No private markup or resources are tracked.
|
||||
The Spanish extra dropdown choices remain a Jotform Builder review item, with
|
||||
fixed Astro context/locale URLs verified. See
|
||||
[focused evidence and remaining acceptance](phase-9-drawer-portal-corrections-2026-10-30.md).
|
||||
@@ -0,0 +1,228 @@
|
||||
# Focused consultation completion and portal presentation correction
|
||||
|
||||
Date: 2026-10-30 UTC. Starting branch `faithful-astro-migration`, starting HEAD
|
||||
`e97f0ea9b475715a1ea58110a27cdf50a2b3cb19`. Tracked tree and index were clean;
|
||||
no untracked paths were reported at preflight. The checkpoint is the commit
|
||||
containing this report; no push, deployment, Jotform mutation or real submission
|
||||
is part of this correction.
|
||||
|
||||
## Completion contract and implementation
|
||||
|
||||
[Jotform Support](https://www.jotform.com/answers/30198031-detect-succesfull-submission)
|
||||
and its linked screenshot were inspected. The screenshot shows an object
|
||||
containing `action: 'submission-completed'` and string `formID` emitted by the
|
||||
thank-you document. It is provider documentation, not a captured submission
|
||||
from AIA Form A. The earlier automated support response on the same thread
|
||||
does not describe this contract; the later human support reply does.
|
||||
|
||||
The receiver is installed only for authorized consultation drawers. It requires:
|
||||
|
||||
- Open, non-closing drawer with an activated consultation iframe.
|
||||
- `event.source` equal to that iframe's actual `contentWindow`.
|
||||
- Exact origin equal to the trusted server-rendered URL's origin:
|
||||
`https://form.jotform.com`. No suffix, substring or wildcard match.
|
||||
- Exact action and string Form A ID `262946078314059` matching that fixed URL.
|
||||
- No prior completion for this frame instance.
|
||||
|
||||
Object envelopes and JSON strings of at most 4096 characters are supported.
|
||||
Malformed, numeric-ID, unrelated and untrusted envelopes are rejected. Extra
|
||||
fields are neither collected nor logged. The receiver uses the existing gated
|
||||
URL instead of embedding a production ID/origin in a shared off-mode bundle.
|
||||
No cross-origin DOM inspection, message forwarding, tracking or submission
|
||||
handler was introduced. The official resize helper remains absent.
|
||||
This trusted-window UI signal is not an independent server-side receipt audit.
|
||||
|
||||
On acceptance, the current global key
|
||||
`aia:service-inquiry:auto-suppressed-until` immediately receives a 30-day expiry.
|
||||
The drawer reveals “Thank you! Your message has been received.” or
|
||||
“¡Gracias! Hemos recibido su mensaje.” above the iframe and scrolls it into view.
|
||||
The existing thank-you document remains untouched. The full 5000ms interval
|
||||
precedes the existing 500ms slide-out; reduced motion removes only the animation.
|
||||
Focus then returns through the existing close mechanism.
|
||||
|
||||
Duplicates do not extend the timer or expiry. Manual close cancels the countdown
|
||||
and retains suppression; navigation removes listeners/timers. Completed state
|
||||
survives lifecycle reinitialization. A subsequent deliberate CTA replaces the
|
||||
completed frame with a fresh node, clears only its fallback/load state, and
|
||||
activates the same fixed URL. Old WindowProxy messages then fail source checks.
|
||||
Incomplete frames remain intact across ordinary close/reopen. Load, validation,
|
||||
clicks and timeout never count as completion.
|
||||
|
||||
The four-second/half-scroll opening rules, manual override, shared suppression,
|
||||
bilingual text, no-JS fallback, sandbox, no-referrer and seven-production versus
|
||||
nine-consultation-test route boundaries are unchanged.
|
||||
|
||||
## Portal presentation and evidence limits
|
||||
|
||||
Both streams use the same scoped presentation: blue section/subsection headings,
|
||||
vertical spacing, list indentation, directories, orange action buttons and
|
||||
visible focus. Only a narrow compatibility vocabulary maps to a local button
|
||||
class: `hs-button`, `content-button`, `portal-resource-button`, or an exact
|
||||
inline AIA orange background (`#ffbd59`/`#ff914d`). Styles themselves are never
|
||||
copied. Contact destinations receive a dark-orange `#a94600` underline treatment
|
||||
for readable contrast against white; buttons retain AIA orange/blue tokens.
|
||||
Table `scope` and numeric spans 1–99 preserve directory semantics.
|
||||
|
||||
Arbitrary classes, inline style/event handlers, scripts, forms, remote styles,
|
||||
iframes/media and unsafe URLs remain removed. Crypto, access-code handling,
|
||||
ciphertext, resource mapping and publication gates are unchanged.
|
||||
|
||||
The legitimate private footer was checked only for unencrypted stylesheet/class
|
||||
semantics; none were available. No real code was supplied and no actual stream
|
||||
was decrypted. Button tokens are narrow compatibility candidates, not verified
|
||||
real-view class inventory. Synthetic staff and management encrypted fixtures
|
||||
exercise both class-based and exact brand-fill mappings. Source-faithful
|
||||
restoration in the actual two views needs owner comparison; do not claim
|
||||
pixel parity or expose decrypted HTML to obtain that evidence. No employee
|
||||
resources, credentials, original HTML or real ciphertext were put in Git,
|
||||
screenshots or public static assets.
|
||||
|
||||
## Spanish dropdown diagnosis
|
||||
|
||||
The owner observed five English service options and seven Spanish options,
|
||||
including `Pregunta general` and `Programar una visita guiada`. Generated URLs:
|
||||
|
||||
| Locale | Exact consultation URL |
|
||||
|---|---|
|
||||
| EN | `https://form.jotform.com/262946078314059?formContext=consultation&language=en` |
|
||||
| ES | `https://form.jotform.com/262946078314059?formContext=consultation&language=es` |
|
||||
|
||||
The three standalone and six drawer mappings use the same fixed form/context;
|
||||
only the locale differs. The parent does not create an extra intent question,
|
||||
preselect services, alter iframe fields or forward page queries. In test mode
|
||||
legacy drawer controls are absent from the active collection surface.
|
||||
|
||||
Likely boundary: Jotform multilingual option translations or Update Options /
|
||||
show-hide conditions retaining inquiry choices in Spanish. This is an inference
|
||||
from source and owner observations, not a Builder audit. Owner should open the
|
||||
direct hosted ES consultation URL and compare with EN and the embedded form.
|
||||
If the direct ES version also shows seven choices, review translations of the
|
||||
correct service question and every condition that changes its options. Preserve
|
||||
contact/landing behavior and verify exactly five consultation choices in both
|
||||
languages. No Jotform configuration or client-side workaround was attempted.
|
||||
|
||||
## Verification
|
||||
|
||||
- Focused unit/isolation/artifact suites: 31 passing tests (including two new
|
||||
tests for completion-envelope validation and narrow portal presentation).
|
||||
- Existing service/portal guarded browser suite: 47 grouped checks, 34 captures,
|
||||
all six service routes at 320/390/768/1440px plus completion lifecycle checks
|
||||
in EN/ES and both synthetic portal views. Evidence:
|
||||
`/tmp/aia-service-portal-eqwVDU/evidence.json`.
|
||||
- Browser environment: repository Nix browser shell, Playwright 1.61.1,
|
||||
Chromium `149.0.7827.55` (actual executable version, not the earlier report's
|
||||
Chromium 151 baseline). No new npm dependency or environment configuration.
|
||||
- Focused correction rerun: 14 overlapping grouped checks, 10 captures,
|
||||
`/tmp/aia-service-portal-CX1fu8/evidence.json`. This rerun adds explicit visible
|
||||
viewport bounds and viewport-only acknowledgment screenshots. CSS-transition
|
||||
time is allowed separately from virtual JavaScript timer time. Both checks
|
||||
passed; overlapping counts are not additional unique route coverage.
|
||||
- Desktop synthetic staff, mobile synthetic management and Spanish completion
|
||||
screenshots were visually inspected. Browser automation is not real
|
||||
screen-reader or fluent-language acceptance.
|
||||
- The full browser run recorded 37 Jotform GET attempts fulfilled by local
|
||||
fixtures; focused rerun recorded six. All non-loopback requests were intercepted
|
||||
before transmission. Zero POST/DELETE, WebSocket, production API, analytics or
|
||||
advertising requests were attempted. Zero external browser requests were sent.
|
||||
|
||||
Reproduction from the existing browser development shell, after the isolated
|
||||
build, is `node tools/service-portal-browser.mjs --correction-only`; omit that
|
||||
flag to include existing timing/scroll/suppression regressions. Every external
|
||||
request is intercepted, service workers are blocked, and portal ciphertext is
|
||||
synthetic response injection. Screenshots remain outside Git.
|
||||
|
||||
Evidence JSON SHA-256 values:
|
||||
|
||||
- Full regression: `5ed8661fdec3a289f43aedeb17113586e4935542cf665ab94759d3aac8794d7a`.
|
||||
- Focused correction: `36bc4804e86fe1d59c9547b8a629a45bef8baac10e34799b845fa1e7642e69fd`.
|
||||
|
||||
Final validation:
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| `npm run check` (also executed by builds) | 151 files; zero errors, warnings, hints |
|
||||
| `node --experimental-strip-types --test --test-concurrency=1 tools/*.test.mjs` | 202 passed, zero failed/skipped; includes Markdown, publication, SEO, Library, routes, campaign, Phase 8, form preview/isolation/artifact and service/portal suites |
|
||||
| `npm run audit:links` | Zero broken internal links |
|
||||
| `npm run audit:images` | Zero missing mapped page images |
|
||||
| `npm run audit:blog` | Zero content failures |
|
||||
| `git diff --check` | Passed |
|
||||
|
||||
Documentation link review covered six changed documents. New links resolve.
|
||||
One preexisting migration-summary link targets the archived
|
||||
`route-reconciliation-2026-10-20-offline.json`; it is a historical reference
|
||||
already documented by the handoff archive inventory, not an active dependency.
|
||||
It remains preserved, and no archived report was read or modified.
|
||||
|
||||
Every mode ran `npm run build` and the matching
|
||||
`node tools/phase10-artifact-verify.mjs --mode=...`:
|
||||
|
||||
| Build | Routes | Sitemap URLs | Hreflang | Immediate Form A frames | Deferred frames |
|
||||
|---|---:|---:|---:|---:|---:|
|
||||
| Isolated test, all consultation flags approved | 128 | 0 | 0 | 10 | 6 |
|
||||
| Fully approved production artifact (local only) | 127 | 109 | 180 | 7 | 0 |
|
||||
| Indexing, forms off | 127 | 109 | 180 | 0 | 0 |
|
||||
| Mock (staging verifier) | 128 | 0 | 0 | 0 | 0 |
|
||||
| Final restored off staging | 128 | 0 | 0 | 0 | 0 |
|
||||
|
||||
All artifact checks passed with zero active native form actions. Final staging
|
||||
has `noindex,nofollow` throughout. Production compilation never authorizes
|
||||
deployment. Temporary review `/lp` remains absent from indexing artifacts.
|
||||
Logs and sanitized artifact results are `/tmp/aia-correction-*.log` and
|
||||
`/tmp/aia-correction-*-artifact.json`; no historical reconciliation was overwritten.
|
||||
|
||||
During development, the artifact verifier correctly rejected an early shared
|
||||
bundle containing the Form A ID. The receiver now derives expected origin/ID
|
||||
from the already authorized iframe URL; subsequent off/mock and gated artifact
|
||||
checks pass without weakening the verifier. Browser full-page captures were
|
||||
supplemented with viewport acknowledgment captures and visible-bounds assertions.
|
||||
|
||||
For consultation testing, set the existing six required values:
|
||||
|
||||
```sh
|
||||
PUBLIC_AIA_FORMS_MODE=isolated-test \
|
||||
PUBLIC_AIA_FORMS_ENVIRONMENT=isolated-test \
|
||||
PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED=true \
|
||||
PUBLIC_AIA_FORMS_LIVE_APPROVED=false \
|
||||
PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED=true \
|
||||
PUBLIC_ALLOW_INDEXING=false npm run build
|
||||
```
|
||||
|
||||
These settings are command-scoped; no local or deployed environment file changed.
|
||||
|
||||
## Changed files
|
||||
|
||||
Implementation:
|
||||
|
||||
- `src/utils/jotform-completion.ts` (new strict completion validator).
|
||||
- `src/scripts/service-inquiry.ts` (completion lifecycle and suppression).
|
||||
- `src/components/ServiceInquiryDrawer.astro` (localized acknowledgment).
|
||||
- `src/components/JotformIframe.astro` (controlled completed-frame reset).
|
||||
- `src/utils/portal-presentation.ts` (new narrow presentation mapper).
|
||||
- `src/scripts/employee-portal.ts` (passive presentation/semantic mapping).
|
||||
- `src/components/pages/EmployeePortal.astro` (scoped styles).
|
||||
|
||||
Tests: `tools/service-portal.test.mjs`, `tools/service-portal-browser.mjs`.
|
||||
Documentation: this report, `reports/SESSION_HANDOFF.md`,
|
||||
`reports/phase-9-form-a-owner-acceptance-2026-10-28.md`,
|
||||
`reports/phase-9-two-form-integration-specification-2026-10-28.md`,
|
||||
`reports/migration-summary.md`, `integrations/employee-portal/README.md`.
|
||||
All paths above are relative to `www/`.
|
||||
|
||||
## Owner acceptance and remaining blockers
|
||||
|
||||
1. Perform one real synthetic consultation submission manually on the approved
|
||||
isolated preview. Confirm actual `action`, `formID` and sender origin without
|
||||
recording submitted answers; verify five seconds, native confirmation,
|
||||
suppression, focus restoration, and fresh manual reopening. If the provider
|
||||
changes origin/shape, the listener intentionally fails closed. Do not broaden
|
||||
trust based on an unverified message. Check both locales' presentation.
|
||||
2. Resolve the Spanish dropdown in Builder after comparing the direct hosted
|
||||
form; confirm five choices, requiredness and language-specific validation.
|
||||
3. Privately unlock both portal views and compare report buttons, directory
|
||||
spacing and focus on desktop/mobile. Supply only sanitized class semantics
|
||||
for any missing style mapping. Real resource access control/cutover remain
|
||||
separate decisions.
|
||||
|
||||
Seven production-eligible Form A routes remain unchanged. Production consultation
|
||||
routes, portal cutover and site cutover remain unauthorized. No approval gate
|
||||
is closed by fixtures, static artifacts or this checkpoint.
|
||||
@@ -57,3 +57,28 @@ The owner reports that Form A now has a `consultation` context with the required
|
||||
The new routes require the separate `PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED=true` flag together with every isolated-test gate. They remain absent from normal staging, mock, indexing-enabled, production-gated and deployed artifacts. The existing seven Form A contact/landing production-eligible routes are unchanged.
|
||||
|
||||
The current decision supersedes the earlier plan for a conditional Autism Diagnostic Evaluation explanation. Do not display that note. The AIA client advocate will discuss evaluation options and coordination with qualified diagnostic providers in follow-up. Owner acceptance is still required for the actual dropdown's visibility, requiredness, choices, translations, conditional behavior, embedded submission/confirmation, error behavior and all nine route presentations.
|
||||
|
||||
## 2026-10-30 completion-message and language diagnostic addendum
|
||||
|
||||
The focused correction adds a narrow first-party completion listener only to
|
||||
authorized consultation drawers. This explicitly supersedes any earlier blanket
|
||||
no-message-listener description for that scope; it does not adopt Jotform's
|
||||
resize handler or permit arbitrary origin messages. The support screenshot
|
||||
documents `{ action: 'submission-completed', formID: '<form ID>' }`.
|
||||
Exact origin, actual active iframe window, fixed Form A ID, open drawer and
|
||||
idempotence are checked before acknowledgment/suppression and five-second closure.
|
||||
No payload is logged, forwarded or used for analytics. Load is not success.
|
||||
|
||||
Owner acceptance **remains pending** for the provider's real envelope and origin,
|
||||
EN/ES acknowledgment, thank-you visibility, full delay, focus restoration and
|
||||
fresh-form reopening. Previous owner-reported direct/embedded acceptance is
|
||||
preserved; it does not establish this newly added message contract.
|
||||
|
||||
The owner reports five English service choices but seven Spanish choices,
|
||||
including General Question/Tour translations. Repository URL tests confirm fixed
|
||||
consultation context and locale only; no service options originate in Astro.
|
||||
Compare the direct hosted ES URL with the embedded result without submitting;
|
||||
if both show seven choices, review Jotform multilingual translations and all
|
||||
Update Options/show-hide conditions, including interaction with the inquiry
|
||||
question. This is a Builder-boundary diagnosis, not an independently observed
|
||||
Jotform configuration audit. No Jotform change is authorized or performed here.
|
||||
@@ -123,3 +123,23 @@ navigation change, new iframe allowance or publication entry. All original
|
||||
seven production and nine isolated consultation placements remain unchanged.
|
||||
No diagnostic conditional note or service preselection is introduced. The
|
||||
clinical and fluent-language review gates remain open.
|
||||
|
||||
### 2026-10-30 completion and language correction addendum
|
||||
|
||||
On a strictly validated Form A `submission-completed` message, an open activated
|
||||
consultation drawer records the same shared suppression expiry immediately,
|
||||
shows localized acknowledgment for five seconds, then uses the existing
|
||||
slide-out/close/focus-restoration flow. The 500ms slide-out follows the full
|
||||
five-second acknowledgment; reduced motion closes immediately after that delay.
|
||||
Manual close/navigation cancels timers. A duplicate message is inert. A later
|
||||
manual CTA starts a fresh iframe after completion; an unfinished iframe is
|
||||
retained. This is not analytics, conversion measurement or answer inspection.
|
||||
The exact source window and exact origin from the gated URL must match. No new
|
||||
production route is approved. Provider behavior still requires owner acceptance.
|
||||
|
||||
The owner-reported Spanish seven-option dropdown conflicts with the intended
|
||||
five choices. Astro emits one fixed consultation iframe per surface; EN/ES differ
|
||||
only in language. No option identifiers, duplicate intent field or service
|
||||
preselection are emitted by Astro. Owner must compare the hosted Spanish form,
|
||||
then review multilingual option translations and Update Options conditions.
|
||||
Do not remove options through cross-origin scripts or add another physical form.
|
||||
Reference in new issue
Block a user