Files
red/.planning/phases/16-multi-signer-ui/16-02-SUMMARY.md
2026-04-03 16:27:13 -06:00

2.4 KiB
Raw Blame History

phase: 16-multi-signer-ui plan: "02" subsystem: ui tags: [react, typescript, preparepanel, signer-list, send-block-validation] # Dependency graph requires: - phase: 16-multi-signer-ui plan: "01" provides: signers prop, onSignersChange, onUnassignedFieldIdsChange threaded from DocumentPageClient provides: - SIGNER_COLORS palette constant ['#6366f1', '#f43f5e', '#10b981', '#f59e0b'] - Signer list UI in PreparePanel (email input + "Add Signer" button + colored dot rows + aria-labeled × remove) - handleAddSigner / handleRemoveSigner with duplicate/format validation - Send-block validation: fetch fields → check no-signers guard → check unassigned isClientVisibleField fields - Inline error messages: "Add at least one signer..." and "{N} field(s) need a signer assigned..." - signers persisted to documents.signers via prepare POST body affects: [16-04-dashboard-badge]

Phase 16 Plan 02: PreparePanel Signer List UI Summary

What Was Built

Modified PreparePanel.tsx (+104 lines) and prepare/route.ts (+5 lines):

PreparePanel.tsx:

  • SIGNER_COLORS = ['#6366f1', '#f43f5e', '#10b981', '#f59e0b'] — auto-assigned by index
  • Props destructured: signers, onSignersChange, onUnassignedFieldIdsChange
  • handleAddSigner — validates email format + duplicate, assigns next color from palette, calls onSignersChange
  • handleRemoveSigner — filters signer from list, clears unassignedFieldIds
  • Signer list UI section (Draft-only, inserted above Prepare and Send):
    • Email <input> + "Add Signer" <button> (height 32px)
    • Per-signer row: 8×8px colored dot (w-2 h-2 rounded-full) + email text + × remove button with aria-label="Remove signer {email}" (32×32px touch target)
    • Empty state: "No signers added yet."
    • Duplicate email warning: "That email is already in the signer list."
  • handlePrepare extended: fetches current fields via /api/documents/{id}/fields, checks unassigned isClientVisibleField fields, sets unassignedFieldIds and shows inline error if found
  • signers included in prepare POST body so documents.signers is persisted before send route reads it

prepare/route.ts:

  • Body type extended with signers?: DocumentSigner[]
  • DB update spreads { signers: body.signers } when provided

Tech tracking

tech-stack: added: [] removed: [] changed: []

Metrics

duration: 4min commit: 1c8551c