[object Object]

← back to Norma

docs: modal training one-pager for SDCC staff (companion to walkthrough video)

fb319b11334bf34de19573b6f0d0c21a5d543291 · 2026-05-20 10:51:42 -0700 · Steve Abrams

Covers all 9 admin-tier modals — Manage Tabs, Add Petition, Petition Draft
(AI), Add Grant, Compose Email, AI Member Email, Schedule, Bulk Schedule,
Compare. Each section: purpose, where to open, key fields, what saves to
PG, gotchas. Common patterns + troubleshooting + data-flow table at the end.

Pairs with the modal walkthrough video being built by app-demo-video skill
(output at ~/.claude/skills/app-demo-video/output/norma-modals-tour/).

Files touched

Diff

commit fb319b11334bf34de19573b6f0d0c21a5d543291
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed May 20 10:51:42 2026 -0700

    docs: modal training one-pager for SDCC staff (companion to walkthrough video)
    
    Covers all 9 admin-tier modals — Manage Tabs, Add Petition, Petition Draft
    (AI), Add Grant, Compose Email, AI Member Email, Schedule, Bulk Schedule,
    Compare. Each section: purpose, where to open, key fields, what saves to
    PG, gotchas. Common patterns + troubleshooting + data-flow table at the end.
    
    Pairs with the modal walkthrough video being built by app-demo-video skill
    (output at ~/.claude/skills/app-demo-video/output/norma-modals-tour/).
---
 docs/MODAL-TRAINING.md | 213 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 213 insertions(+)

diff --git a/docs/MODAL-TRAINING.md b/docs/MODAL-TRAINING.md
new file mode 100644
index 0000000..66905a9
--- /dev/null
+++ b/docs/MODAL-TRAINING.md
@@ -0,0 +1,213 @@
+# Norma — Modal Training Guide
+
+> Companion reference for the modal walkthrough video. One page covering all 9 admin-tier modals: where to open them, what each field does, and what happens when you save.
+
+**Login:** `admin / DWSecure2024!` at `/login` → "Continue with email".
+**Tier:** All 9 modals below are visible to the **admin** and **staff (SDCC)** tiers. The public **Pulse** tier sees a separate flow.
+
+---
+
+## 1. Manage Tabs
+
+**Purpose:** Show or hide tabs in the left sidebar. Lets each staff member tailor Norma to the work they actually do — a grants person can hide Social, a comms person can hide Pipeline.
+
+**Open:** Bottom-left of the sidebar, the small gear icon labeled "Manage Tabs" (`aria-label="Manage Tabs"`).
+
+**What you'll see**
+- A scrollable list of every tab in Norma, grouped by section.
+- An eye icon next to each — click to toggle visibility.
+- A search box at the top ("Filter tabs…") to find a tab by name.
+- A "Reset All" link to bring everything back.
+
+**Result:** Preferences save to your account. The change is instant and survives reloads.
+
+**Watch out for:** Hiding a tab does NOT delete data. It just removes the sidebar entry. Unhide it anytime to get back in.
+
+---
+
+## 2. Add Petition (admin-side)
+
+**Purpose:** Create or import a petition from inside the admin shell. Different from the public Pulse `/pulse/petitions/create` page — this version supports MoveOn / Change.org URL imports and lets you set fields a public visitor can't.
+
+**Open:** Petitions tab → "New Petition" button (top-right of the tab).
+
+**Key fields**
+- **Title** — required, action-oriented, e.g. "Protect the SAVE Plan"
+- **URL / Platform** — if importing from MoveOn or Change.org, paste the petition URL and Norma will fetch metadata
+- **Description / Body** — the persuasive text
+- **Target** — who is being asked to act (e.g. "U.S. Department of Education")
+- **Category** — debt cancellation, consumer protection, voting rights, legal, education, etc.
+- **Signature goal**
+- **Status** — active / draft (drafts are not visible on Pulse)
+- **Featured** — pins it to the Pulse homepage hero rotation
+
+**Result:** Inserts a row in `petitions` table. If `allow_signatures=true` it shows up on Pulse for signing. If you set `is_featured=true`, it lands in the homepage carousel.
+
+**Watch out for:** The 30-minute dedup window — submitting the same title twice within half an hour will MERGE the new fields into the existing row rather than creating a duplicate. This is intentional (see commit `9619a2a`).
+
+---
+
+## 3. Petition Draft (AI-generated)
+
+**Purpose:** Norma's News Intelligence and Topic Radar surface stories worth turning into petitions. This modal opens with an AI-drafted petition based on that topic — title, body, talking points, target, all pre-filled.
+
+**Open:** Pipeline tab → click a draft row. Also: Pulse Feed → "Draft Petition" on any topic card. Also: Topic Radar → "Draft from this topic" button.
+
+**What you'll see**
+- A `topic` prop drives the initial fill — the news headline + summary becomes the petition draft.
+- Auto-detect button — leave fields blank and Norma will fill them.
+- Pre-filled title, body, talking points (4–5), target, category — all editable.
+- A side-by-side view of the source article so you can fact-check.
+
+**Result:** Saves the draft to `petitions` with `status='draft'`. Won't go live until you flip status to `active`.
+
+**Watch out for:** AI suggestions can pull dates and stats from the article — always proofread the talking points before publishing. Don't ship a petition citing a stat you haven't verified.
+
+---
+
+## 4. Add Grant
+
+**Purpose:** Log a new grant opportunity into the Grants pipeline. Tracks the funder, amount range, deadline, eligibility, and proposal status.
+
+**Open:** Grants tab → "Add Grant" button (top-right).
+
+**Key fields**
+- **Name** — e.g. "Student Loan Borrower Assistance Grant"
+- **Funder** — e.g. "Ford Foundation"
+- **Funder URL**
+- **Amount range** — min & max (e.g. $25,000 – $250,000)
+- **Description**
+- **Eligibility** — who can apply
+- **Application URL**
+- **Deadline** — date picker
+- **Status** — researching / drafting / submitted / awarded / declined
+
+**Result:** Row inserted into `grants` table; appears in the Grants pipeline kanban.
+
+**Watch out for:** If the funder is already in the `foundations` table, link to it rather than re-typing — keeps the org graph clean.
+
+---
+
+## 5. Compose Email
+
+**Purpose:** Draft an outbound email from inside the admin shell. The most-used modal in Norma. Pulls in news context, lets the AI draft the body, then queues for review and send.
+
+**Open:** Multiple entry points
+- News tab → "Compose" on a news item (prefills with headline + summary)
+- Email Center → "New Email" button
+- From a contact card → "Email this person"
+- Outreach Playbook → "Start sequence from this template"
+
+**Key fields**
+- **Subject** — required
+- **Context** — what is this email about? Feeds the AI generator.
+- **AI Generate** button — drafts body from subject + context + optional news item
+- **Body** — the email body. Editable, AI-augmented. Supports image drop/paste.
+- **Recipient** — single contact, list, or saved segment
+- **Boilerplate insert** — one-click blocks for sign-offs, disclaimers, donation links
+
+**Result:** Saves a row to `drafts`. From the Email Center, drafts can be sent via Gmail (natalia@studentdebtcrisis.org) or queued in a sequence.
+
+**Watch out for:** Image drag-drop uploads inline. Norma stores image URLs, not the binary — make sure the image host is reliable before sending.
+
+---
+
+## 6. AI Member Email Generator
+
+**Purpose:** Member-targeted broadcast emails. Takes a short brief ("housing bill passed committee") and a few bullet points and generates a complete, on-brand member email.
+
+**Open:** Dashboard tab → "AI Member Email" button in the action row (look for the cyan border on hover).
+
+**Key fields**
+- **Subject hint** — e.g. "New housing bill passes committee vote"
+- **Bullet points** — 3–5 short bullets the AI will expand into prose
+- **Tone** — informative / urgent / celebratory / advocacy
+- **Audience segment** — all members / signed petition X / state Y / district Z
+
+**Result:** Generates a draft email. Drops you into the Compose modal pre-filled, so you can review and send through the standard pipeline.
+
+**Watch out for:** "All members" is a big list — confirm the segment count before sending. The send is real, not a dry-run.
+
+---
+
+## 7. Schedule (single content)
+
+**Purpose:** Schedule any piece of content — a petition launch, a grant proposal step, a pipeline action, a statement publish — to fire at a specific time.
+
+**Open:** Reused across Pipeline, Grants, Petitions, and Statements tabs. Look for the "Schedule" or clock icon next to any row.
+
+**Key fields**
+- **When** — date + time picker
+- **What** — content type is pre-filled (`petition` / `grant` / `pipeline` / `statement`) and read-only
+- **Title** — read-only, shows you what's being scheduled
+
+**Result:** Row inserted into `scheduled_dispatches` table. Norma's cron will fire the action at the scheduled time.
+
+**Watch out for:** Schedule times are in your local timezone, but stored as UTC. The display always shows your local time. If you're scheduling for a different time zone (e.g. a 9am ET press release from a West Coast staffer), do the math.
+
+---
+
+## 8. Bulk Schedule (social)
+
+**Purpose:** Schedule multiple social posts at once. Drop in a list of post bodies (one per line, or upload a CSV/TXT), pick the channels, set cadence — Norma spreads them out automatically.
+
+**Open:** Social tab → "Bulk Schedule" button.
+
+**Key fields**
+- **Posts** — paste or upload. One post per line, or CSV with `body,channel,time` columns.
+- **Channels** — checkboxes for Twitter/X, Facebook, Instagram, LinkedIn
+- **Cadence** — "every N hours" / "specific times each day" / "manual times per post"
+- **Start date**
+
+**Result:** Multiple rows in `social_schedule`. Posts queue and fire at scheduled times via the respective platform APIs.
+
+**Watch out for:** Channel API limits — IG and FB throttle bursty posting. Spread > 4 posts/day, not 4 in 10 minutes, or you'll trip rate limits.
+
+---
+
+## 9. Compare (email analyzer)
+
+**Purpose:** Side-by-side compare of two versions of the same email. Used after the AI rewrites a draft — see what changed, see the pros/cons of each version, apply a suggestion as a chat instruction.
+
+**Open:** Email Analyzer → after running an analysis with a "Rewrite" → click "Compare" on the version timeline.
+
+**What you'll see**
+- Version A and Version B side-by-side
+- Pros / Cons panel below, AI-generated, comparing tone, clarity, brand voice
+- "Apply suggestion" buttons — click to send an instruction back into the chat (closes the modal and triggers an AI rewrite)
+
+**Result:** Read-only by default. Clicking "Apply suggestion" closes the modal and pipes the instruction into the chat panel for the AI to act on.
+
+**Watch out for:** Closing the modal does NOT save anything — versions are auto-saved when the AI generates them, not when you close the compare view.
+
+---
+
+## Common patterns across all modals
+
+- **Close:** Click the `×` in the upper-right, or hit `Escape`.
+- **Background:** Most modals dim the page behind. You can't click through to the underlying tab.
+- **Brand:** Admin modals use Norma's dark theme (`#0C0F1A` bg, `#10b981` emerald). Pulse-side modals use the Pulse light theme (cream + dark green + gold).
+- **No autosave:** Drafting in a modal does not autosave. If you close before clicking Save / Publish / Schedule, the work is lost. Exception: the Compose modal saves to `drafts` on every keystroke pause.
+
+## If a modal doesn't open
+
+1. **Refresh** — sometimes a React state hangs. Cmd-R clears it.
+2. **Check tier** — staff (SDCC) tier sees most but not all admin modals. Confirm your login.
+3. **Check the console** — Cmd-Opt-J → Console. A 500 on `/api/...` means the DB is unhappy; check `lib/db.ts` env vars and `psql -d sdcc -c "SELECT 1"`.
+4. **Tier credentials live in PG** — `SELECT username, role FROM tier_credentials;` will show what accounts exist.
+
+## Where the data lives
+
+| Modal | Writes to PG table |
+|---|---|
+| Manage Tabs | `user_preferences` |
+| Add Petition / Petition Draft | `petitions` |
+| Add Grant | `grants` |
+| Compose / AI Member Email | `drafts`, then `email_campaigns` on send |
+| Schedule | `scheduled_dispatches` |
+| Bulk Schedule | `social_schedule` |
+| Compare | nothing — read-only |
+
+---
+
+*Last updated: 2026-05-20. Pairs with the modal walkthrough video at `~/.claude/skills/app-demo-video/output/norma-modals-tour/norma-modals-tour-demo.mp4`.*

← e46e6f9 fix(editor): set immediatelyRender:false on Tiptap useEditor  ·  back to Norma  ·  session 2026-05-20: log 9 task entries (petition debounce, m 4161ee6 →