Files
hermes-skills/skills/software-development/debt-recovery-platform/references/new-letter-modal-flow.md
T

9.0 KiB

"+ New Letter" Modal Flow

Created: 2026-07-08 — added to /var/www/internal/letter-queue.html

Overview

A two-screen modal that replaces the static default claim with a full client-selection → stage-appropriate-template flow. When the user clicks "New Letter" (button with id="newLetterBtn"), the modal opens on the client selection screen.

Screen 1 — Client Selection

Modal Structure

Element Details
Title "New Letter"
Subtitle "Select a client/claim to get started"
Search bar Filter input with search icon, placeholder "Search by debtor name, claim #, or client..."
Body Scrollable list of client rows

Client Data Model (JS clients[])

{
  claim: String,   // "DRE-2026-0142"
  debtor: String,  // "Marcus Bellweather"
  amount: Number,  // 12840.00
  client: String,  // "ABC Construction"
  stage: String    // "soft-touch" | "formal-demand" | "lien-threat" | "escalation" | "legal-action"
}

Client Row Rendering

Each row shows:

  • Left (flex-1, truncate): Debtor name (white, medium) + claim # (amber, mono) on line 1. Client name + amount on line 2 (gray-500, xs).
  • Right (shrink-0): Stage badge (colored pill).

Search filter is case-insensitive and matches against debtor, claim, or client fields.

Stage Badge CSS

.stage-badge { display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 2px 10px; border-radius: 9999px; font-size: 0.7rem;
  font-weight: 600; letter-spacing: 0.02em; border: 1px solid; }

.stage-soft-touch    { background: rgba(59,130,246,0.15); color: #93c5fd; border-color: rgba(59,130,246,0.3); }
.stage-formal-demand { background: rgba(245,158,11,0.15); color: #fcd34d; border-color: rgba(245,158,11,0.3); }
.stage-lien-threat   { background: rgba(251,146,60,0.15); color: #fdba74; border-color: rgba(251,146,60,0.3); }
.stage-escalation    { background: rgba(239,68,68,0.15); color: #fca5a5; border-color: rgba(239,68,68,0.3); }
.stage-legal-action  { background: rgba(168,85,247,0.15); color: #d8b4fe; border-color: rgba(168,85,247,0.3); }
Stage Color Semantic
soft-touch Blue Initial contact
formal-demand Amber First formal notice
lien-threat Orange Lien warning
escalation Red Final warning
legal-action Purple Referred to counsel

Demo Clients (10 claims)

Claim Debtor Amount Client Stage
DRE-2026-0142 Marcus Bellweather $12,840 ABC Construction soft-touch
DRE-2026-0098 Sylvia Chen $8,750 Chen & Sons Roofing formal-demand
DRE-2026-0105 James Kowalski $22,340 Kowalski Framing LLC lien-threat
DRE-2026-0081 Patricia Okafor $5,400 Okafor Drywall Inc. escalation
DRE-2026-0157 Angela Torres $16,780 Torres Electric Co. formal-demand
DRE-2026-0062 Linda Harper $9,200 Harper Painting & More lien-threat
DRE-2026-0074 Robert Nguyen $31,500 Nguyen Construction LLC legal-action
DRE-2026-0118 Derek Simmons $6,400 Simmons Brick & Block soft-touch
DRE-2026-0123 Maria Gonzalez $19,450 Gonzalez Landscaping escalation
DRE-2026-0135 Tom Fletcher $11,000 Fletcher Plumbing LLC soft-touch

Screen 2 — Template Selection

Header Change

When a client is selected, the modal header updates:

  • Title: Debtor's name (e.g. "Marcus Bellweather")
  • Subtitle: "{claim} · ${amount} · Current Stage: {stageLabel}"

Stage-to-Template Progression

Templates always progress forward — you never offer a template at or below the current stage. The mapping:

const stageTemplates = {
  'soft-touch':     ['formal-demand'],
  'formal-demand':  ['lien-threat', 'escalation'],
  'lien-threat':    ['escalation', 'legal-action'],
  'escalation':     ['legal-action'],
  'legal-action':   [] // referred to counsel — no templates
};

Template Display

Each template is rendered as a button with:

  • Icon (colored Font Awesome icon, w-6 text-center)
  • Name (white, medium, sm): e.g. "Formal Demand Letter"
  • Description (gray-500, xs): e.g. "Generate a Soft Touch → Formal Demand Letter"
  • Arrow right (gray-500, ml-auto)

Icons per template:

Template Icon
Formal Demand fa-regular fa-file-lines
Lien Threat fa-regular fa-triangle-exclamation
Escalation / Final Notice fa-regular fa-bell
Legal Action Referral fa-regular fa-gavel

When a client is already at legal-action stage, the template screen shows:

  • Purple gavel icon centered
  • "Legal Action Stage" heading
  • "This claim has been referred to legal counsel. No letter templates are available."
  • "Back to client list" button

Template Content (4 templates)

Each template uses [CLAIM], [DEBTOR], [AMOUNT], [CLIENT] placeholders that get replaced at selection time.

Formal Demand — Standard escalation from soft-touch. 14-day payment window. References previous notice. Lists collection measures (lawsuit, liens, litigation referral). Includes payment URL.

Lien Threat — Texas Property Code mechanic's lien warning. 10-day payment window. Explains that a filed lien attaches to title and affects sale/refinance. Construction-focused language.

Escalation / Final Notice — Strongest pre-legal notice. 10-day ultimatum before lawsuit referral. Lists post-judgment remedies (garnishment, levy, seizure). Mentions court costs and attorney's fees.

Legal Action Referral — Confirms referral to legal counsel. States that a civil petition will be filed. Includes claim/amount/legal reference. Lists what the lawsuit will seek (judgment, interest, costs, fees).

Each template gets appended with:

Sincerely,
Anita Rodriguez
Collections Specialist
Debt Recovery Experts

Selection → Draft Creation

When a template is selected:

  1. Replace placeholders in the template raw content
  2. Append signature block (Anita Rodriguez)
  3. Reset composer — textarea gets the new content, status badge set to Draft, claim info bar updated with client data and stage badge
  4. Create new letter entry — pushed to letters[] with a new auto-incremented id, status draft, authoredBy Anita Rodriguez, tier set to current stage label
  5. Select the new letter via selectLetter(newId) — updates the table with the row highlighted
  6. Close modal
  7. Scroll to composerdocument.querySelector('.grid-layout').scrollIntoView(...)
  8. Toast — "New {templateLabel} drafted for {debtor}"

Modal CSS

.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.7);
  backdrop-filter: blur(4px); display: flex; align-items: center;
  justify-content: center; z-index: 60; }
.modal-overlay.hidden { display: none; }
.modal-panel { background: #1e293b; border: 1px solid #374151;
  border-radius: 16px; width: 100%; max-width: 42rem; margin: 0 1rem;
  max-height: 80vh; display: flex; flex-direction: column;
  box-shadow: 0 25px 60px -15px rgba(0,0,0,0.4); }

.client-row { display: flex; align-items: center; gap: 0.75rem;
  padding: 10px 14px; border-radius: 10px; cursor: pointer;
  transition: background 0.15s; }
.client-row:hover { background: #334155; }
.client-row.selected { background: rgba(245,158,11,0.1);
  border: 1px solid rgba(245,158,11,0.25); }

.template-btn { display: flex; align-items: center; gap: 0.75rem;
  width: 100%; padding: 12px 16px; border-radius: 10px; cursor: pointer;
  transition: all 0.15s; text-align: left; background: #0f172a;
  border: 1px solid #334155; color: #e2e8f0; }
.template-btn:hover { background: #1e293b; border-color: #f59e0b; }
.template-btn + .template-btn { margin-top: 6px; }
.templates-grid { display: grid; grid-template-columns: 1fr; gap: 6px; }

.back-btn { display: inline-flex; align-items: center; gap: 0.375rem;
  color: #94a3b8; font-size: 0.8125rem; cursor: pointer;
  transition: color 0.15s; }
.back-btn:hover { color: #f59e0b; }

JS Functions (key)

Function Purpose
openNewLetterModal() Resets state, clears search, shows modal, renders client list, focuses search
closeNewLetterModal() Hides modal
renderModalClientList() Filters clients[] by modalSearchQuery, renders rows or empty state
showTemplatesForClient(client) Updates title/subtitle, renders available templates or legal-action disabled state
selectTemplate(client, templateKey) Replaces placeholders, appends signature, creates draft letter, selects it, closes modal, scrolls to composer

Edge Cases

  • Empty search results: Centered exclamation icon + "No clients match {query}" message
  • Legal-action clients: Disabled template screen with "referred to counsel" message, no templates offered
  • Modal close on overlay click: Clicking the blurred backdrop closes the modal (same as the X button)
  • Search while on templates screen: Input is only active when modalState === 'clients' — typing during template selection does nothing