Files
hermes-config/skills/self-hosting/shop-pro-quote/references/new-features-2026-06-28.md
T
2026-07-12 10:17:17 -04:00

3.7 KiB

New Features Added 2026-06-28

Settings Page — 8 tabs (was 6)

Two new tabs added:

PDF & Branding Tab

Setting Field Effect
Logo logoUrl (base64 data-URL) Upload PNG/JPG (max 500KB), shows on PDF quotes
Show logo on PDF showLogoOnPdf (boolean) Toggle logo visibility
Quote Expiry (days) quoteExpiryDays (number) Replaces hardcoded "30 days" in PDF footer
Quote Number Prefix quoteNumberPrefix (string) Prepended to quote IDs on PDF
Accent Color pdfAccentColor (hex string) Color picker — changes green accent on PDF headers/badges

Business Ops Tab

Setting Field Effect
Tax Label taxLabel (string) Rename "Tax" to "Sales Tax", "HST", etc.
Payment Terms paymentTerms (string) Shown on invoices/quotes ("Due on Receipt", "Net 15", "Net 30")
Default Labor Rate defaultLaborRate (number) Preset $/hr when adding catalog services
Business Hours businessHours (string) Free-text or JSON schedule for appointment system

Files changed: types.ts (ShopSettings), pages/Settings.tsx (PDFBrandingSection + BusinessOpsSection components), lib/pdf.ts (reads new fields)

PDF generator integration:

  • const ACCENT: ColorTuple = settings.pdfAccentColor ? hexToRgb(settings.pdfAccentColor) : GR — replaces hardcoded GR color
  • Footer uses settings.quoteExpiryDays instead of hardcoded 30
  • Tax line uses settings.taxLabel instead of hardcoded "Tax"
  • Logo renders via doc.addImage() on page 1
  • Payment terms appear in summary section

Replaced the Recent Quotes table (desktop) + card list (mobile) with a custom dropdown component:

  • Trigger button: "Jump to a recent quote…" with rotating chevron
  • Search input: Pinned at top of panel, filters by customer name / RO# / vehicle info
  • Result rows: Each shows customer name + RO# on one line, vehicle + date below, total + status badge on the right
  • Behavior: click-outside-to-close, auto-focus on search when opened, query resets on navigation

Shop Charge Defaults to true

In ServiceSearch.handleAdd(), applyShopCharge now defaults to true instead of undefined:

addService({ ...service, selected: true, approved: true, customerDecision: 'approved', priority: undefined, applyShopCharge: true });

Previously the checkbox was unchecked by default and the shop charge was $0.00/hidden unless the user manually checked it on each service. The per-service toggle still exists for exceptions.

AI Write Now Includes Technician Notes

handleAiWrite in QuoteGenerator.tsx now passes technicianNotes: svc.technicianNotes to aiWriteExplanation. The existing prompt builder in ai.ts already handles it:

if (technicianNotes) {
  additionalContext += `\nTechnician's internal notes: "${technicianNotes}"`;
}

So the AI-generated explanation incorporates the tech's internal notes as context.

PDF-to-Images Export

New file: src/lib/pdf-to-images.ts

downloadPdfAsImages(pdfInput: jsPDF | Blob, customerName: string): Promise<void>

Accepts either a jsPDF instance or a Blob. Converts every page to PNG via pdfjs-dist and triggers a download per page: Jon_Smith_Page1.png, Jon_Smith_Page2.png, etc.

Setup required:

  • npm install pdfjs-dist
  • Worker config in main.tsx: pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString()
  • Scale configurable via getViewport({ scale }) (default 2 = Retina)

Button added in QuoteGenerator QuoteSummary: blue border "Export as Images" button between Print and Save.