2026-03-16 23:20:54 +01:00
|
|
|
export type RuntimeRecordType = 'role' | 'dashboard' | 'onboarding';
|
|
|
|
|
export type RuntimeRecordStatus = 'draft' | 'published';
|
|
|
|
|
|
|
|
|
|
const KEY = 'nxtgauge_admin_runtime_builder_v1';
|
|
|
|
|
|
|
|
|
|
type RuntimeStore = {
|
2026-03-16 23:30:37 +01:00
|
|
|
role: Record<string, RuntimeStoredRecord<unknown>>;
|
|
|
|
|
dashboard: Record<string, RuntimeStoredRecord<unknown>>;
|
|
|
|
|
onboarding: Record<string, RuntimeStoredRecord<unknown>>;
|
2026-03-16 23:20:54 +01:00
|
|
|
};
|
|
|
|
|
|
2026-03-16 23:30:37 +01:00
|
|
|
export type RuntimeStoredRecord<T> = {
|
|
|
|
|
status: RuntimeRecordStatus;
|
|
|
|
|
updatedAt: string;
|
|
|
|
|
payload: T;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export type RuntimeListItem<T> = RuntimeStoredRecord<T> & {
|
|
|
|
|
key: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function emptyStore(): RuntimeStore {
|
|
|
|
|
return { role: {}, dashboard: {}, onboarding: {} };
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-16 23:20:54 +01:00
|
|
|
function readStore(): RuntimeStore {
|
2026-03-16 23:30:37 +01:00
|
|
|
if (typeof window === 'undefined') return emptyStore();
|
2026-03-16 23:20:54 +01:00
|
|
|
const raw = window.localStorage.getItem(KEY);
|
2026-03-16 23:30:37 +01:00
|
|
|
if (!raw) return emptyStore();
|
|
|
|
|
|
2026-03-16 23:20:54 +01:00
|
|
|
try {
|
|
|
|
|
const parsed = JSON.parse(raw) as Partial<RuntimeStore>;
|
|
|
|
|
return {
|
|
|
|
|
role: parsed.role || {},
|
|
|
|
|
dashboard: parsed.dashboard || {},
|
|
|
|
|
onboarding: parsed.onboarding || {},
|
|
|
|
|
};
|
|
|
|
|
} catch {
|
2026-03-16 23:30:37 +01:00
|
|
|
return emptyStore();
|
2026-03-16 23:20:54 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeStore(store: RuntimeStore) {
|
|
|
|
|
if (typeof window === 'undefined') return;
|
|
|
|
|
window.localStorage.setItem(KEY, JSON.stringify(store));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveRuntimeConfig(type: RuntimeRecordType, key: string, payload: unknown, status: RuntimeRecordStatus) {
|
2026-03-16 23:30:37 +01:00
|
|
|
const normalizedKey = key.trim();
|
|
|
|
|
if (!normalizedKey) return;
|
|
|
|
|
|
2026-03-16 23:20:54 +01:00
|
|
|
const store = readStore();
|
2026-03-16 23:30:37 +01:00
|
|
|
store[type][normalizedKey] = {
|
2026-03-16 23:20:54 +01:00
|
|
|
status,
|
|
|
|
|
updatedAt: new Date().toISOString(),
|
|
|
|
|
payload,
|
|
|
|
|
};
|
|
|
|
|
writeStore(store);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-16 23:30:37 +01:00
|
|
|
export function listRuntimeConfigs<T>(type: RuntimeRecordType): Array<RuntimeListItem<T>> {
|
|
|
|
|
const store = readStore();
|
|
|
|
|
return Object.entries(store[type])
|
|
|
|
|
.map(([key, value]) => ({ key, ...(value as RuntimeStoredRecord<T>) }))
|
|
|
|
|
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRuntimeConfig<T>(type: RuntimeRecordType, key: string): RuntimeStoredRecord<T> | null {
|
|
|
|
|
const record = readStore()[type][key];
|
|
|
|
|
return (record as RuntimeStoredRecord<T>) || null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteRuntimeConfig(type: RuntimeRecordType, key: string): boolean {
|
|
|
|
|
const store = readStore();
|
|
|
|
|
if (!store[type][key]) return false;
|
|
|
|
|
delete store[type][key];
|
|
|
|
|
writeStore(store);
|
|
|
|
|
return true;
|
|
|
|
|
}
|