1.7 KiB
1.7 KiB
Settings Persistence Pattern (ShopProQuote)
Architecture
Settings live in two places:
- localStorage (
spq-settingskey) — always available, even without login - PocketBase
settingscollection — per-user JSON field (datafield), only when logged in
Loading order (Settings.tsx init)
loadLocalSettings()→ reads localStorage, spreads over DEFAULT_SETTINGS- If logged in, fetch PB record → spread
{ ...DEFAULT_SETTINGS, ...data }over the storeddataJSON field saveLocalSettings(merged)— overwrites localStorage with PB data so next load uses it
Saving
updateSetting(key, value)— updates local state + immediately writes to localStoragesaveAllSettings()— saves to PocketBase (if logged in) + localStorage
Type: ShopSettings (src/types.ts)
export interface ShopSettings {
businessName: string;
businessAddress: string;
businessPhone: string;
serviceAdvisor: string;
taxRate: number;
taxLabel: string;
shopChargeRate: number;
shopChargeExplanation: string;
headerMessage: string;
footerMessage: string;
quoteFooterNote: string;
// PDF & Branding
logoUrl?: string;
showLogoOnPdf: boolean;
quoteExpiryDays: number;
quoteNumberPrefix: string;
pdfAccentColor: string;
// Business Ops
businessHours?: string;
defaultLaborRate: number;
paymentTerms: string;
}
DEFAULT_SETTINGS lives in two places
Both MUST stay in sync:
src/pages/Settings.tsx(the settings UI uses this)src/pages/QuoteGenerator.tsx(the PDF generator'sloadSettings()fallback)
When adding a new setting: add to types.ts → add to both DEFAULT_SETTINGS → add UI field → add to pdf.ts usage.