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

78 lines
3.7 KiB
Markdown

# 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
## Dashboard — Custom Dropdown with Search
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:
```typescript
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:
```typescript
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.