mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 23:53:05 +00:00
Codify feel-the-action as a campaign UI principle.
Add PRODUCT.md guidance on immediate control feedback and honest pending states, plus a Cursor rule for campanha and public interactive surfaces.
This commit is contained in:
parent
a1167849ea
commit
8d8fee0914
2 changed files with 30 additions and 1 deletions
28
.cursor/rules/campanha-action-feedback.mdc
Normal file
28
.cursor/rules/campanha-action-feedback.mdc
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
description: Immediate action feedback, pending UI, and optimistic controls (campanha + public)
|
||||
globs: src/app/(campaign)/**/*,src/components/campaign/**/*,src/app/(frontend)/**/*,src/components/**/*
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Feel the action
|
||||
|
||||
Canonical principle: `PRODUCT.md` § Design Principles — **Feel the action**. Precedents: `ActionPlanFilters` / `PlazaFilters` / `SupporterFilters` (`useTransition` + `data-pending` + `aria-busy` + live region); form submits with `useActionState` pending + `Spinner`.
|
||||
|
||||
When adding or changing an interactive control that triggers navigation, revalidation, or a server action:
|
||||
|
||||
1. **Immediate feedback on the trigger (<~100ms).** The control must change state at once — selected value, pressed/disabled, spinner on the button — so the user knows the tap registered. Do not leave a select bound only to stale server props while RSC is still loading.
|
||||
2. **Optimistic on the control; honest on the result.** Keep local/optimistic state for filter selects, toggles, and draft input. Keep the server (URL + RSC / action result) as source of truth for lists, maps, KPIs, and persisted fields — show pending on _that_ region until refresh completes; roll back the control if the action fails.
|
||||
3. **Pending pattern.** Prefer `useTransition` (URL/`router`) or `useActionState`/`pending` (mutations). Set `aria-busy` and a polite live region (e.g. “Atualizando resultados…”, “Salvando…”). Dim or skeleton the changing region (`data-pending`); do not rely on `sr-only` alone when the wait is multi-second.
|
||||
4. **Classify before coding.** (a) URL filter/nav → local control value + transition pending on results. (b) Form mutation → disable submit + spinner/label. (c) Lazy/heavy open → keep trigger mounted; loading/error states on the shell (existing campaign lazy-dialog pattern).
|
||||
5. **Does not override Edit where you see.** In-context edit still revalidates; this rule forbids silent waits and stale-looking controls, not server refresh. Anti-goal shared with that principle: inventing list/aggregate data client-side and skipping refresh.
|
||||
|
||||
## Anti-goals
|
||||
|
||||
- Control stuck on the previous value until navigation finishes (classic filter-select bug)
|
||||
- Full-page spinner as the only pending signal
|
||||
- Fake/indeterminate progress that implies completion percentage
|
||||
- Pending with no `aria-busy` / live region on multi-second waits
|
||||
|
||||
## Plan / Impeccable brief
|
||||
|
||||
For UI items: answer explicitly — _does every action on this surface feel immediate on the control, with honest pending on the result?_ Cite this principle; name rabbit hole “optimistic list without refresh” when scoping.
|
||||
|
|
@ -42,10 +42,11 @@ Not generic SaaS dashboards (purple gradients, hero-metric templates, identical
|
|||
|
||||
1. **Sovereignty as the horizon** — own audience, data, and ops over time; Big Tech shortcuts (WhatsApp kits, share links) are fine for now when they help mobilization, but design should keep the campaign’s own records and workflows as the source of truth and leave room to reduce platform dependency later.
|
||||
2. **Clarity under pressure** — every screen earns its keep for field use; prefer plain language and obvious next actions over decoration.
|
||||
3. **Edit where you see** — on `/campanha` staff surfaces (coordinator / advisor), mutable data that the role can update should be editable in context whenever it fits (list cell, detail card, queue row), so assessors and the general coordinator do not burn time navigating to a separate edit screen for every correction. Prefer named Popovers / selects / short inputs that reuse existing server actions and the same access rules as the full form. Keep dedicated `/editar` (or long Sheets) for multi-field strategy forms, rare fields, and anything that needs a note or confirmation flow. Leadership paths stay read-or-declare as already scoped — never expose staff-only fields. Anti-goals: full-row spreadsheet / data-grid mode; always-mounted inputs on every row; a second generic “editable cell” design system; optimistic writes that skip server refresh when the list is the source of truth.
|
||||
3. **Edit where you see** — on `/campanha` staff surfaces (coordinator / advisor), mutable data that the role can update should be editable in context whenever it fits (list cell, detail card, queue row), so assessors and the general coordinator do not burn time navigating to a separate edit screen for every correction. Prefer named Popovers / selects / short inputs that reuse existing server actions and the same access rules as the full form. Keep dedicated `/editar` (or long Sheets) for multi-field strategy forms, rare fields, and anything that needs a note or confirmation flow. Leadership paths stay read-or-declare as already scoped — never expose staff-only fields. Anti-goals: full-row spreadsheet / data-grid mode; always-mounted inputs on every row; a second generic “editable cell” design system; optimistic _writes of list/aggregate results_ that skip server refresh when the list is the source of truth (optimistic control state is fine — see Feel the action).
|
||||
4. **Depth and simplicity as peers** — staff workflows can be rich; leadership paths stay light and phone-first without becoming a second-class product.
|
||||
5. **Intelligence serves organization** — electoral baseline and insights exist to decide where to act, not to impress.
|
||||
6. **Inspire without kitsch** — socialist and mobilizing in spirit; never shouty campaign brochure aesthetics.
|
||||
7. **Feel the action** — every user-initiated action (filter, save, URL-driven refresh, opening a heavy sheet) must give **immediate** feedback on the control or surface that was touched — under ~100ms perceived response. Prefer optimistic UI for the _control value_ (select shows the chosen option at once; button shows pending) while the _result_ (list, map, KPIs, detail payload) shows honest pending (`aria-busy`, live region, opacity/skeleton on the region that changes) until the server/RSC catches up. Applies to `/campanha` first (field pressure) and to public interactive flows the same way. Anti-goals: silent waits where the control stays on the old value until navigation finishes; full-page spinner as the only feedback; fake progress bars; omitting accessible busy/live announcements.
|
||||
|
||||
## Accessibility & Inclusion
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue