Files
hermes-config/skills/self-hosting/shop-pro-quote/references/phone-formatting.md
T
2026-07-12 10:17:17 -04:00

2.1 KiB

Phone Number Formatting

All phone numbers in SPQ are stored as raw digits (no formatting) and displayed/input as 555-555-5555 (hyphen-separated, no parentheses).

Shared Utility: src/lib/phone.ts

Two exports:

  • formatPhoneInput(raw: string): string — live input mask for onChange. Strips non-digits, inserts hyphens as user types.

    • """"
    • "555""555"
    • "5555""555-5"
    • "5555555555""555-555-5555"
  • formatPhoneDisplay(phone: string | null | undefined): string — display formatter for read-only contexts (tables, PDFs, previews).

    • "5555555555""555-555-5555"
    • "5551234""555-1234" (7-digit fallback)
    • Handles legacy formatted data (strips parens, spaces, dots).

Input Pattern (onChange + value)

For every phone <input>:

import { formatPhoneInput } from '../lib/phone';

// In the input:
value={formatPhoneInput(phoneValue)}
onChange={(e) => setPhone(e.target.value.replace(/\D/g, ''))}
placeholder="555-555-5555"

This stores raw digits (stripped on every keystroke) and displays the mask.

Display Pattern

For every read-only phone render:

import { formatPhoneDisplay } from '../lib/phone';

// In JSX:
{formatPhoneDisplay(customer.phone)}
// In template literals:
`${formatPhoneDisplay(inv.customerPhone)}`

Files Using Phone Formatting

File Applied
QuoteGenerator.tsx CustomerInfoPanel phone field
ROForm.tsx RO create/edit phone field
Appointments.tsx 3 inputs + list display
Invoices.tsx 1 input + printable HTML + preview
Customers.tsx 1 input + 2 displays (card + detail)

Pitfalls

  • Stored data may be legacy-formattedformatPhoneDisplay and formatPhoneInput both strip non-digits first, so legacy (555) 555-5555 data is handled.
  • Don't store the formatted value — the onChange handler must strip formatting (.replace(/\D/g, '')) so PocketBase only contains raw digits.
  • Don't create local formatPhone functions — always import from src/lib/phone.ts. Duplicate implementations exist in legacy code and should be replaced.