import type { CommunityStructureChipSnapshotRow } from "../../app/(app)/create/types"; import type { Stage } from "./deckTypes"; /** * Stable chip ids for Create Community. Old drafts stored a 1-based position. * Enterprise and Larger organization both load as Established. */ const SIZE_BY_POSITION = [ "oneMember", "twoToFive", "sixToTwelve", "thirteenToOneHundred", "oneHundredToOneHundredK", ] as const; const ORG_BY_POSITION = [ "workersCoop", "mutualAid", "openSource", "nonprofit", "forProfit", "dao", ] as const; const SCALE_BY_POSITION = ["local", "regional", "national", "global"] as const; const MATURITY_BY_POSITION = [ "earlyStage", "growthStage", "established", "established", ] as const; const MATURITY_LABEL_ALIASES: Record = { "Early stage": "earlyStage", "Growth stage": "growthStage", Established: "established", Enterprise: "established", "Larger organization": "established", }; const ORG_LABEL_ALIASES: Record = { "Worker cooperative": "workersCoop", "Worker co-op": "workersCoop", "Mutual aid": "mutualAid", "Open source project": "openSource", Nonprofit: "nonprofit", "For profit business": "forProfit", DAO: "dao", }; function fromPosition( id: string, positions: readonly string[], ): string | null { if (!/^\d+$/.test(id)) return null; const index = Number(id) - 1; if (index < 0 || index >= positions.length) return null; return positions[index] ?? null; } export function resolveSizeChipId(id: string): string { return fromPosition(id, SIZE_BY_POSITION) ?? id; } export function resolveOrgChipId(id: string, label?: string): string { if (label && ORG_LABEL_ALIASES[label]) return ORG_LABEL_ALIASES[label]; return fromPosition(id, ORG_BY_POSITION) ?? id; } export function resolveScaleChipId(id: string): string { return fromPosition(id, SCALE_BY_POSITION) ?? id; } export function resolveMaturityChipId(id: string, label?: string): string { if (label && MATURITY_LABEL_ALIASES[label]) return MATURITY_LABEL_ALIASES[label]; if (id === "enterprise" || id === "larger-organization") return "established"; return fromPosition(id, MATURITY_BY_POSITION) ?? id; } export function resolveChipIdList( ids: readonly string[] | undefined, resolve: (id: string) => string, ): string[] | undefined { if (!ids) return undefined; const out: string[] = []; const seen = new Set(); for (const id of ids) { const next = resolve(id); if (!next || seen.has(next)) continue; seen.add(next); out.push(next); } return out; } type PresetChip = { id: string; label: string }; /** * Rewrite a saved chip snapshot onto the current preset ids and labels. * Custom rows stay. Several maturity answers stay, as distinct ids. */ export function migrateChipSnapshot( rows: CommunityStructureChipSnapshotRow[] | undefined, presets: readonly PresetChip[], resolve: (id: string, label?: string) => string, ): CommunityStructureChipSnapshotRow[] | undefined { if (!rows || rows.length === 0) return rows; const presetIds = new Set(presets.map((p) => p.id)); const selected = new Set(); const customs: CommunityStructureChipSnapshotRow[] = []; for (const row of rows) { const nextId = resolve(row.id, row.label); if (presetIds.has(nextId)) { if (row.state === "selected") selected.add(nextId); continue; } customs.push({ ...row, id: nextId }); } return [ ...presets.map((preset) => ({ id: preset.id, label: preset.label, state: selected.has(preset.id) ? "selected" : "unselected", })), ...customs, ]; }