wizard admin feature in existing crm as separate route
This commit is contained in:
@@ -174,11 +174,20 @@ export const DISCLAIMER_TEMPLATE =
|
||||
'insurance professional. Historical storm information is not a forecast or guarantee.';
|
||||
|
||||
export const TENANT_CONFIG_VERSION = 'tenant-config-v1';
|
||||
export const DISCLAIMER_VERSION = 'disclaimer-v1';
|
||||
|
||||
export function getTenantConfig() {
|
||||
// Phase 5 admin page will override these from localStorage / mock store.
|
||||
// Admin-editable overrides persist here (spec §14). The wizard merges them over
|
||||
// the defaults so pricing/branding/feature flags are tenant-controlled, not code.
|
||||
const CONFIG_STORAGE_KEY = 'lup_estimate_wizard_config_v1';
|
||||
|
||||
function defaults() {
|
||||
return {
|
||||
version: TENANT_CONFIG_VERSION,
|
||||
disclaimerVersion: DISCLAIMER_VERSION,
|
||||
// Feature flags (spec §18): kill-switch, AI toggle, conservative copy mode.
|
||||
featureEnabled: true,
|
||||
aiExplanationsEnabled: true,
|
||||
conservativeMode: false,
|
||||
packages: DEFAULT_PACKAGES,
|
||||
addons: DEFAULT_ADDONS,
|
||||
scoringWeights: DEFAULT_SCORING_WEIGHTS,
|
||||
@@ -187,6 +196,41 @@ export function getTenantConfig() {
|
||||
discountScenarios: DEFAULT_DISCOUNT_SCENARIOS,
|
||||
branding: DEFAULT_BRANDING,
|
||||
disclaimer: DISCLAIMER_TEMPLATE,
|
||||
conservativeMode: false, // §18: hides customer-facing savings claims when true
|
||||
};
|
||||
}
|
||||
|
||||
export function loadConfigOverrides() {
|
||||
try {
|
||||
const raw = localStorage.getItem(CONFIG_STORAGE_KEY);
|
||||
return raw ? JSON.parse(raw) : {};
|
||||
} catch { return {}; }
|
||||
}
|
||||
|
||||
export function saveConfigOverrides(overrides) {
|
||||
try { localStorage.setItem(CONFIG_STORAGE_KEY, JSON.stringify(overrides || {})); } catch { /* quota */ }
|
||||
}
|
||||
|
||||
export function resetConfigOverrides() {
|
||||
try { localStorage.removeItem(CONFIG_STORAGE_KEY); } catch { /* ignore */ }
|
||||
}
|
||||
|
||||
export function getTenantConfig() {
|
||||
const base = defaults();
|
||||
const o = loadConfigOverrides();
|
||||
|
||||
// Shallow-merge top-level objects so partial admin edits don't drop defaults.
|
||||
return {
|
||||
...base,
|
||||
...o,
|
||||
pricing: { ...base.pricing, ...(o.pricing || {}) },
|
||||
branding: { ...base.branding, ...(o.branding || {}) },
|
||||
scoringWeights: { ...base.scoringWeights, ...(o.scoringWeights || {}) },
|
||||
stormSettings: { ...base.stormSettings, ...(o.stormSettings || {}) },
|
||||
discountScenarios: { ...base.discountScenarios, ...(o.discountScenarios || {}) },
|
||||
// Packages: merge admin price/label edits by type, keep default scope/copy.
|
||||
packages: base.packages.map((p) => {
|
||||
const ov = (o.packages || []).find((x) => x.type === p.type);
|
||||
return ov ? { ...p, ...ov } : p;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user