Commit Graph

23 Commits

Author SHA1 Message Date
Joel Brock
04e69ca04c Header: show Civi stage label prominently; restore current_stage readonly in Stage 0
- New STAGE_OPTION_GROUP_ID constant (=75) added to config and consumed
  by both the in-card readonly and the header. Because the field carries
  optionGroupId, /api/data auto-includes the Stage option group in its
  parallel fetch (via the existing optionGroupIds derivation).
- SubmissionContextHeader: dropped the small inline 'Stage Organizing'
  line. Replaced with an uppercase 'Current stage' eyebrow next to the
  progress dots, followed by a display-font 20/24px leaf-toned label
  underneath. Resolves the stored option value ('Organizing') to its
  Civi option label ('Stage 1 — Convene & Prepare') via the new
  resolveStageLabel helper; falls back to the raw value if the option
  group hasn't loaded.
- Stage 0 'Check-in (organizing)' section: re-added a current_stage
  readonly field at the top. With optionGroupId set, FieldRenderer's
  readonly branch resolves the value to the Civi label for display.
2026-05-13 12:09:24 -07:00
Joel Brock
74a85d38fe Drop in-form Framework Stage field; align section labels with Civi
The current_stage readonly field is removed from Stage 0 — the activity-
derived stage value already displays in the SubmissionContextHeader, so
showing it again in-card was redundant. current_stage remains in form
state (RHF defaults from /api/data) because every Stage 1-5 visibleWhen
rule and the journey rail still key off it; it just isn't rendered.

Section labels for Stages 1-5 updated to match the CiviCRM Stage option
group labels exactly (ampersand instead of 'and'; Stage 2 corrected from
'Feasibility' to 'Grow & Plan'). Stage 0 keeps its 'Check-in (organizing)'
label since it represents the always-visible core fields, not the Inquiry
stage rank.

Also folded in: in-progress visibleWhen additions on several Stage 0
fields and commented-out field stubs from your working tree.
2026-05-13 12:04:22 -07:00
Joel Brock
b4e80517a7 Derive current stage from most-recent stage-bearing activity
Stage authority moves from Organization.Food_Co_op_Organizing.Stage to the
most recent Check-in (organizing) activity whose Stage custom field is set.
Staff create these activities manually to mark transitions; org-owner form
submissions no longer write the Stage field at all, so they cannot override
a staff-set transition.

- /api/data: removed the Contact.get for org-side Stage; added an
  Activity.get filtered to ACTIVITY_TYPE_NAME + ACTIVITY_STAGE_FIELD IS
  NOT EMPTY, ordered by activity_date_time DESC, id DESC, limit 1.
  Fallback when no such activity exists: Inquiry (rank 0). Org-name
  lookup, stage activity, prefill, and option-group fetch all run in
  parallel via Promise.all.
- /api/submit: removed the stageAtSubmission read + the
  [ACTIVITY_STAGE_FIELD] write on the activity record. The form's
  activities are stage-null by design now.
- config/form.ts: dropped the stage_at_submission readonly field (no
  longer being set or displayed). Kept ACTIVITY_STAGE_FIELD export — it's
  now used by /api/data to find stage-bearing activities. Updated the
  current_stage field comment to reflect the new source.
- components/EngagementForm.tsx: dropped stage_at_submission from
  evalState (no longer referenced by any visibility rule or readonly
  display).

Org.Food_Co_op_Organizing.Stage remains in CiviCRM for staff list views;
the middleware no longer reads or writes it. No backfill required —
orgs without a stage-bearing activity simply read as Inquiry.
2026-05-13 11:41:25 -07:00
Joel Brock
18b7a67fa1 Swap inline 'Sown' SVG for the real FCI brand logo
Drops the stylized SVG mark in favor of public/fci-logo.png (the official
Food Co-op Initiative logo, including its wordmark). Because the logo now
contains the 'Food Co-op Initiative' text, the duplicate display-font
wordmark is removed; the 'Co-op Check-in' eyebrow stays as a quiet hairline
divider to the right (sm+ only, hidden on mobile to keep the header tight).
2026-05-11 13:42:06 -07:00
Joel Brock
762605f04b Compact the journey rail to reclaim form width
Gutter shrinks from md:pl-20 (80px) to md:pl-12 (48px) — a 32px (40%) gain
back to the form column. Markers, pulse halo, and 'Now' pill scale down to
match so the rail still reads at a glance:

- Marker container: -left-14 w-12 -> -left-9 w-7
- Past/future markers: h-6 -> h-5
- Current marker: h-7 ring-4 -> h-6 ring-2; rank label 11px -> 10px
- 'Now' pill: 9px -> 8px; tracking and offset re-balanced for the shorter
  drop from the smaller marker bottom
- Rail-pulse keyframe shadow radius: 8px -> 6px to suit the smaller disc
2026-05-11 13:37:28 -07:00
Joel Brock
9103ccaf9d Locked future-stage cards + journey rail
Future stages now render as preview-only "look ahead" cards instead of being
hidden. A user at stage 2 can see headers and contents for stages 3, 4, 5,
but those sections are visibly locked and uneditable.

Locked-card treatment:
- Dashed-rule border, paper-2 fill, no shadow — visually quieter than
  active cards
- "Upcoming" pill in the header with a small lock glyph
- Muted stage rank mark (dashed badge, low-opacity icon)
- Panel content wrapped in fieldset[disabled] so every form control inside
  is natively non-interactive, with an opacity tweak for affordance
- "A look ahead" banner explaining that fields will become editable when
  the co-op reaches this stage

Section visibleWhen is still consulted on submit, so locked-stage values
never get written back to CiviCRM even if data is prefilled.

Journey rail:
- Vertical rail (md+) in a new left gutter; each card carries an aligned
  marker. Past stages = filled leaf circle with check; current = filled
  leaf disc with rank number, leaf-100 halo ring, and a subtle rail-pulse
  box-shadow animation (motion-safe). A "Now" pill sits beneath the
  current marker. Future stages = dashed hollow ring with lock glyph.
- Connector segments between markers are solid leaf when the next stage
  is past-or-current, dashed muted when future — so the transition from
  "traveled" to "ahead" reads at the right place in the journey.
- Mobile fallback: a small vertical stem in the gap between adjacent
  cards, styled the same way (solid vs dashed) so the progression cue
  still reads on narrow viewports.
2026-05-11 13:05:34 -07:00
Joel Brock
a804650f65 Audit short-term: currency preview, date bounds, success destination, safe-area
- H3: Live currency preview below currency inputs shows the value formatted
  with thousands separators (en-US, USD) using Intl.NumberFormat. Skipped
  inside matrix cells to keep the Y1 monthly table compact.
- M1: Date inputs now apply min/max bounds. Default window is 1900-01-01 to
  2100-12-31; per-field override via FieldConfig.min/max as ISO strings.
- H6: On successful submit, replace the form with a SuccessDestination card
  (large checkmark, org name, "Submit another" + "safe to close" affordance).
  Prevents accidental duplicate submits from back-button / autofill replay.
- M6: Sticky submit bar respects iOS safe-area-inset-bottom.

FieldRenderer now takes a control prop so the currency preview can subscribe
to its single field via useWatch without re-rendering the whole form.
2026-05-11 09:48:03 -07:00
Joel Brock
0d84b9654b Polish pass: removed lastTouched dead code, selective useWatch perf, token sweep, required-field messages, scroll-to-first-error, file prefill display, matrix sticky shadow 2026-05-09 22:49:25 -07:00
Joel Brock
e452fbb15f Email delivery: /api/preview-link admin endpoint + EMAIL_DELIVERY.md guide 2026-05-09 22:31:51 -07:00
Joel Brock
442740939e Allow CSP unsafe-eval in dev only (Next.js HMR); production stays strict 2026-05-09 21:51:28 -07:00
Joel Brock
656bf7fd0a Visual identity: Field Almanac — Fraunces+DM Sans, OKLCH cream/leaf/clay palette, paper texture, hand-drawn stage icons, draft auto-save, stage progress dots 2026-05-09 21:48:45 -07:00
Joel Brock
dcdf315244 Production hardening: CSP, rate limit, env validation, health gating, Render blueprint, DEPLOYMENT.md 2026-05-09 21:43:43 -07:00
Joel Brock
da3e48a874 Add matrix-group display for monthly/quarterly time-series fields in Stage 5 2026-05-09 21:29:21 -07:00
Joel Brock
082238d884 Fix Activity.create payload: pass values as object not array 2026-05-09 21:15:56 -07:00
Joel Brock
1655c485d9 Fix APIv4 relationship_type_id join: use dot syntax not colon 2026-05-09 21:10:56 -07:00
Joel Brock
da830af533 Health probe: dump all relationships for a given contact, flag direction issues 2026-05-09 21:08:30 -07:00
Joel Brock
2e9d3855ba Use existing 'Primary Contact' relationship type via FORM_CONTACT_RELATIONSHIP constant 2026-05-09 20:57:29 -07:00
Joel Brock
e132789a3e Sharper health probes: resolve stage option group via CustomField metadata; list near-match relationship types 2026-05-09 20:52:06 -07:00
Joel Brock
82d7849a30 Support webserver-level HTTP Basic Auth in front of CiviCRM 2026-05-09 20:49:37 -07:00
Joel Brock
234bec5766 Add /api/health diagnostic route; remove stale .js route duplicates 2026-05-09 20:45:14 -07:00
Joel Brock
c58a49be6d Wire real CiviCRM DEV custom fields and dynamic option fetching 2026-05-09 20:42:35 -07:00
Joel Brock
54555c74d2 Build standalone CiviCRM check-in middleware 2026-05-09 20:08:15 -07:00
google-labs-jules[bot]
0899e6ae9a Implement CiviCRM middleware form with stage-based visibility
- Initialize Next.js project with Tailwind CSS
- Create CiviCRM APIv4 integration layer
- Implement stage-based form visibility (stages 0-5)
- Add field mapping configuration for CRM-to-form linking
- Create API routes for data retrieval and submission
- Record form submissions as CiviCRM activities
- Support dynamic contactId and orgId via URL parameters
- Ensure robust form state management with react-hook-form

Co-authored-by: joelbrock <52835+joelbrock@users.noreply.github.com>
2026-05-09 08:12:39 +00:00