wizard admin feature in existing crm as separate route

This commit is contained in:
Mayur Shinde
2026-06-09 18:01:32 +05:30
parent 0da194b157
commit 075d2dd60f
10 changed files with 695 additions and 9 deletions
@@ -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;
}),
};
}